题意:给一个图,可以染白色和黑色,但是染黑色的结点不能相邻。求最多的黑色结点个数,和一种可能的黑色结点序列。
思路:这个用回溯法还是很容易想到怎么写的。dfs每一个位置,知道所有位置dfs完。对每个位置都尝试黑色和白色。如果染黑色,那么就需要把和它相邻的结点染成白色,因为他们必须是白色,如果发现有相邻结点已经是黑色,则当前结点不能是黑色;而因为dfs后需要对辅助的全局变量进行恢复,所以这里在将相邻结点染成白色前先判断它是不是已经是白色了,因为如果它已经是白色在恢复的时候就不需要再恢复了,否则需要把它恢复成未染色的状态。 程序实现,我用的是color数组,0表示未染色,1表示黑色,2表示白色。dfs只需要对未染色的结点进行详细考虑,其中在染成黑色时用一个数组保存了相邻的、本来就是白色结点的结点编号;已染色的结点只要简单地dfs下一位置即可。
注意:这里结点的编号是从1到n,数组要开够,而且循环的索引及范围要注意下。
第二个,就是要注意全局变量的初始化。这里特别要注意的是g数组的初始化,之前以为反正是要赋值的,就没初始化。。。之后发现边数为0的话,那g数组就是上个数据的了。。其实,就算边数不为0,是其他的数,g数组不初始化的话,上一数据的边的关系还是会残留在这组数据的。。。
第三个,就是输出的时候,给出一种可能的序列就可以了。最后一个数之后没有空格,直接回车。否则会 PE 错误。(终于遇到一次PE了啊,之前记得格式错很多都提示WA的,所以这题第一次WA的时候,怀疑是不是输出的原因,结果并不是。。。)
给一些测试数据:
input
5
6 8
1 2
1 3
2 4
2 5
3 4
3 6
4 6
5 6
2 1
1 2
3 2
1 2
1 3
5 0
8 4
1 2
3 4
5 6
6 8
output
3
1 4 5
1
1
2
2 3
5
1 2 3 4 5
5
1 3 5 7 8
Code:
#include<stdio.h> #include<string.h> void dfs(int cur,int n); int g[102][102]; int color[102]; int bestclr[102]; int bestblk; int main() { //freopen("193.in","r",stdin); //freopen("193.out","w",stdout); int m; scanf("%d",&m); while(m-->0) { bestblk=0; memset(color,0,sizeof(color)); memset(g,0,sizeof(g)); int n,k; scanf("%d%d",&n,&k); int a,b; for(int i=0;i<k;++i) { scanf("%d%d",&a,&b); g[a][b]=1; g[b][a]=1; } dfs(1,n); printf("%d\n",bestblk); //for(int i=0;i<=n;++i) if(bestclr[i]==1) printf("%d ",i); //printf("\n"); int num=0; int i=1; for(;i<=n;++i) { if(num==bestblk-1) break; if(bestclr[i]==1) { printf("%d ",i); num++;} } for(;i<=n;++i) if(bestclr[i]==1) { printf("%d\n",i); break;} } return 0; } void dfs(int cur,int n) { if(cur==n+1) { int num=0; for(int i=1;i<=n;++i) if(color[i]==1) num++; if(num>bestblk) { bestblk=num; memcpy(bestclr,color,sizeof(color));} return ; } if(color[cur]==0) { color[cur]=1;//黑色 int ok=1; int tempnd[n]; int cnt=0; for(int j=1;j<=n;++j) if(g[cur][j]) { if(color[j]==1) { ok=0; break;} else if(color[j]==0) { color[j]=2;} else tempnd[cnt++]=j;//保留原来就是白色的结点编号 } if(ok) dfs(cur+1,n); //恢复 for(int j=1;j<=n;++j) if(g[cur][j]&&color[j]==2) { int flag=1; for(int i=0;i<cnt;++i) if(tempnd[i]==j) { flag=0; break;} if(flag) color[j]=0; } color[cur]=0; dfs(cur+1,n); } else dfs(cur+1,n); }
原文地址:http://blog.csdn.net/buxizhizhou530/article/details/44152219