-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMaximumClique.cpp
More file actions
67 lines (57 loc) · 1.6 KB
/
Copy pathMaximumClique.cpp
File metadata and controls
67 lines (57 loc) · 1.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "bits/stdc++.h"
#define ALL(g) (g).begin(),(g).end()
#define REP(i, x, n) for(int i = x; i < n; i++)
#define rep(i,n) REP(i,0,n)
#define RREP(i, x, n) for(int i = x; i >= n; i--)
#define rrep(i, n) RREP(i,n,0)
#define pb push_back
using namespace std;
using ll = long long;
using P = pair<int,int>;
using Pl = pair<ll,int>;
const int mod=1e9+7,INF=1<<30;
const double EPS=1e-12,PI=3.1415926535897932384626;
const ll lmod = 1e9+7,LINF=1LL<<60;
const int MAX_N = 41;
vector<int> graph[40];
bool ok1[1<<20],ok2[1<<20];
int ok3[1<<20],dp[1<<20];
int main() {
int N,M; cin >> N >> M;
rep(i,M){
int a,b; cin >> a >> b;
a--; b--; graph[a].pb(b); graph[b].pb(a);
}
int n1 = (N+1)/2; int n2 = N/2;
fill(ok1,ok1+(1<<n1),true);
rep(i,n1) for(auto u:graph[i]) if(u<n1) ok1[(1<<i)|(1<<u)] = false;
rep(i,1<<n1) if(!ok1[i]) rep(j,n1) ok1[i|(1<<j)] = false;
fill(ok2,ok2+(1<<n2),true);
REP(i,n1,N) for(auto u:graph[i]) if(u>=n1) ok2[(1<<(i-n1))|(1<<(u-n1))] = false;
rep(i,1<<n2) if(!ok2[i]) rep(j,n2) ok2[i|(1<<j)] = false;
ok3[0] = (1<<n2) - 1;
rep(i,n1){
ok3[1<<i] = (1<<n2) - 1;
for(auto u:graph[i]) if(u>=n1) ok3[1<<i] ^= (1<<(u-n1));
}
rep(i,1<<n1) rep(j,n1) ok3[i|(1<<j)] = ok3[i]&ok3[1<<j];
rep(i,1<<n2){
if(ok2[i]){
int cnt = 0;
rep(j,n2) if(i&(1<<j)) cnt++;
dp[i] = cnt;
}else{
dp[i] = 0;
}
}
rep(i,1<<n2) rep(j,n2) dp[i|(1<<j)] = max(dp[i|(1<<j)],dp[i]);
int ans = 0;
rep(i,1<<n1){
if(!ok1[i]) continue;
int cnt = 0;
rep(j,n1) if(i&(1<<j)) cnt++;
ans = max(ans,cnt + dp[ok3[i]]);
}
cout << ans << endl;
return 0;
}