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

 

你可能感兴趣的:(poj)