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 }
Bron–Kerbosch算法

代码君:

 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 }
代码君

 

posted @ 2015-03-30 16:19  UsedRose  阅读(247)  评论(0编辑  收藏  举报