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 */

 

 

posted @ 2012-08-09 10:37  pushing my way  阅读(1322)  评论(0编辑  收藏  举报