POJ1419 Graph Coloring

问题描叙:

对一个给定的图找出最佳着色,只能用黑色和白色,着色规则是任何相连接的节点不可能同时都是黑色。

分析:这题是典型的求最大独立集,有个定理(这里就不写证明了):图的最大独立集=它的补图的最大团。

所以先构造器补图,然后计算补图的最大团,先按照序号递减的顺序,依次将节点i作为当前的第i各节点,然后将节点i+1到n中与节点i邻接的点置在一个集合里(get)

程序中:

map[][]为图(在输入的时候就变换成了原图的补图)

ans[]为当前的最大团结果序列。

dp[i]表示节点i到n之间最大团个数。

get[i][]表示当前有两个已经进入最大团时,其中最后一个节点k(表示当前最大团里的i个节点序号最后的那个节点)之后与它相连接的节点集合。

M表示最大团的个数(随着DFS的进行,持续更新)

DFS完成整个程序,贴上代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define MAX 110
 4 bool map[MAX][MAX];
 5 int n,M,sum,sum1;
 6 int ans[MAX],dp[MAX],get[MAX][MAX],node[MAX];
 7 void dfs(int now,int sum)
 8 {
 9     int i,j,v;
10     if(sum==0){
11         if(now>=M){
12             M=now;
13             for(i=1;i<=M;i++)
14                 ans[i]=node[i];
15         }
16         return ;
17     }
18     for(i=1;i<=sum;i++){
19         v=get[now][i],sum1=0;
20         if(now+dp[v]<M) return ;
21         for(j=i+1;j<=sum;j++)
22             if(map[v][ get[now][j] ]) get[now+1][++sum1]=get[now][j];
23         node[now+1]=v;
24         dfs(now+1,sum1);
25     }
26 }
27 void slove()
28 {
29     memset(dp,0,sizeof(dp));
30     memset(get,0,sizeof(get));
31     int i,j;
32     M=0;
33     for(i=n;i>=1;i--){
34         sum=0,node[1]=i;
35         for(j=i+1;j<=n;j++)
36             if(map[i][j]) get[1][++sum]=j;
37         dfs(1,sum);
38         dp[i]=M;
39     }
40     printf("%d\n",M);
41     for(i=1;i<=M;i++)
42         printf("%d ",ans[i]);
43     printf("\n");
44 }
45 void init()
46 {
47     int k,i,x,y;
48     memset(map,true,sizeof(map));
49     scanf("%d%d",&n,&k);
50     for(i=1;i<=k;i++){
51         scanf("%d%d",&x,&y);
52         map[x][y]=map[y][x]=false;
53     }
54 }
55 int main()
56 {
57     int N;
58     scanf("%d",&N);
59     while(N--){
60        init();
61        slove();
62     }
63     return 0;
64 }
View Code

 

 

posted on 2014-03-06 16:09  静夜方赤  阅读(606)  评论(0编辑  收藏  举报

导航