poj1419_染色_最大独立集_最大团
题意:
经典的图的染色问题,求对于给定的无向图中,给每个结点染两种不同颜色(黑色和白色)的一种且相邻结点的颜色不同,求染成黑色的最多结点数。
分析:
这个题求的图的最大独立集,最大独立集即为黑色节点的个数。
由于原图的最大独立集=补图的最大团。
而这个题是普通图,所以用回溯法来做,时间复杂度O(n*2^n)
代码:
View Code
1 #include <iostream> 2 #include <memory.h> 3 #include <stdio.h> 4 using namespace std; 5 6 const int maxnum=101; 7 bool array[maxnum][maxnum]; 8 bool use[maxnum]; //进入团的标号 9 bool bestx[maxnum]; 10 int cn,bestn,p,e; 11 12 void dfs(int i) 13 { 14 int j; 15 bool flag; 16 17 if(i>p) 18 { 19 bestn=cn; //cn的值是递增的 20 // printf("%d\n",bestn); 21 // for(j=1;j<=p;j++) 22 // if(use[j]) 23 // printf("%d ",j); 24 // printf("\n"); 在这里输出不一定是最大团 25 for(j=1;j<=p;j++) //而是应该赋值给另外一个数组, 26 bestx[j]=use[j]; 27 return ; 28 } 29 30 flag=true; 31 for(j=1;j<i;j++) 32 if(use[j]&&!array[j][i]) 33 { 34 flag=false; 35 break; 36 } 37 if(flag) 38 { 39 cn++; 40 use[i]=true; 41 dfs(i+1); 42 cn--; 43 } 44 if(cn+p-i>bestn) //剪枝 45 { 46 use[i]=false; 47 dfs(i+1); 48 } 49 } 50 51 int main() 52 { 53 int num,i,u,v; 54 scanf("%d",&num); 55 while(num--) 56 { 57 memset(array,true,sizeof(array)); 58 memset(use,false,sizeof(use)); 59 memset(bestx,false,sizeof(bestx)); 60 scanf("%d%d",&p,&e); 61 for(i=0;i<e;i++) 62 { 63 scanf("%d%d",&u,&v); 64 array[u][v]=false; 65 array[v][u]=false; 66 } 67 68 cn=bestn=0; 69 dfs(1); 70 printf("%d\n",bestn); 71 for (i=1; i<=p; i++) 72 if(bestx[i]) 73 printf("%d ",i); 74 printf("\n"); 75 } 76 77 return 0; 78 } 79 80 /* 81 1 82 5 7 83 1 2 84 1 4 85 1 5 86 2 3 87 2 5 88 3 5 89 4 5 90 */