poj 1419 (最大独立集)
基础知识:
最大独立集: 顶点集V中取 K个顶点,其两两间无连接。
最大团: 顶点集V中取 K个顶点,其两两间有边连接。
最大独立集 = 补图的最大团。 (补图 = 完全图 - 原图)
挺详细的解释:http://www.cnblogs.com/yefeng1627/archive/2013/03/31/2991592.html
思路:
据说。。求原图的最大独立集是NP问题,那么就可以通过求其补图中最大团中顶点数量,就可得出原图中最大独立集中顶点数量了.
附上优化后的模板:
1 #include<cstdio> 2 #include<cstring> 3 #define N 1010 4 bool flag[N], a[N][N]; 5 int ans, cnt[N], group[N], n, vis[N]; 6 // 最大团: V中取K个顶点,两点间相互连接 7 // 最大独立集: V中取K个顶点,两点间不连接 8 // 最大团数量 = 补图中最大独立集数 9 10 bool dfs( int u, int pos ){ 11 int i, j; 12 for( i = u+1; i <= n; i++){ 13 if( cnt[i]+pos <= ans ) return 0; 14 if( a[u][i] ){ 15 // 与目前团中元素比较,取 Non-N(i) 16 for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break; 17 if( j == pos ){ // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中 18 vis[pos] = i; 19 if( dfs( i, pos+1 ) ) return 1; 20 } 21 } 22 } 23 if( pos > ans ){ 24 for( i = 0; i < pos; i++ ) 25 group[i] = vis[i]; // 最大团 元素 26 ans = pos; 27 return 1; 28 } 29 return 0; 30 } 31 void maxclique() 32 { 33 ans=-1; 34 for(int i=n;i>0;i--) 35 { 36 vis[0]=i; 37 dfs(i,1); 38 cnt[i]=ans; 39 } 40 }
代码君:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip> 10 #include<climits> 11 #include<string.h> 12 #include<numeric> 13 #include<cmath> 14 #include<stdlib.h> 15 #include<vector> 16 #include<stack> 17 #include<set> 18 #define FOR(x, b, e) for(int x=b;x<=(e);x++) 19 #define REP(x, n) for(int x=0;x<(n);x++) 20 #define INF 1e7 21 #define MAXN 100010 22 #define maxn 1000010 23 #define Mod 1000007 24 #define N 1010 25 using namespace std; 26 typedef long long LL; 27 28 29 bool flag[N], a[N][N]; 30 int ans, cnt[N], group[N], n, m, vis[N]; 31 bool dfs(int u, int pos){ 32 int i, j; 33 for (i = u + 1; i <= n; i++){ 34 if (cnt[i] + pos <= ans) return 0; 35 if (a[u][i]){ 36 // 与目前团中元素比较,取 Non-N(i) 37 for (j = 0; j < pos; j++) if (!a[i][vis[j]]) break; 38 if (j == pos){ // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中 39 vis[pos] = i; 40 if (dfs(i, pos + 1)) return 1; 41 } 42 } 43 } 44 if (pos > ans){ 45 for (i = 0; i < pos; i++) 46 group[i] = vis[i]; // 最大团 元素 47 ans = pos; 48 return 1; 49 } 50 return 0; 51 } 52 53 void maxclique() 54 { 55 ans = -1; 56 for (int i = n; i > 0; i--) 57 { 58 vis[0] = i; 59 dfs(i, 1); 60 cnt[i] = ans; 61 } 62 } 63 64 int main(){ 65 int T; 66 scanf("%d", &T); 67 while (T--){ 68 scanf("%d%d", &n, &m); 69 int x, y; 70 memset(a, 0, sizeof(a)); 71 for (int i = 0; i < m; i++){ 72 scanf("%d%d", &x, &y); 73 a[x][y] = a[y][x] = 1; 74 } 75 for (int i = 1; i <= n; i++) 76 for (int j = 1; j <= n; j++) 77 if (i == j) a[i][j] = 0; 78 else a[i][j] ^= 1; 79 maxclique(); 80 81 if (ans < 0) ans = 0; 82 printf("%d\n", ans); 83 for (int i = 0; i < ans; i++) 84 printf(i == 0 ? "%d" : " %d", group[i]); 85 if (ans > 0) puts(""); 86 } 87 return 0; 88 }