Victoria是一位颇有成就的艺术家,他因油画作品《我爱北京天安门》闻名于世界。现在,他为了报答帮助他的同行们,准备开一个舞会。
Victoria准备邀请n个已经确定的人,可是问题来了:
这n个人每一个人都有一个小花名册,名册里面写着他所愿意交流的人的名字。比如说在A的人名单里写了B,那么表示A愿意与B交流;但是B的名单里不见的有A,也就是说B不见的想与A交流。但是如果A愿意与B交流,B愿意与C交流,那么A一定愿意与C交流。也就是说交流有传递性。
Victoria觉得需要将这n个人分为m组,要求每一组的任何一人都愿意与组内其他人交流。并求出一种方案以确定m的最小值是多少。
注意:自己的名单里面不会有自己的名字。
以下是我的AC代码,写得很传统。
但是我仍有点疑问。
如果A和B互相有好(已经染在一起),发现A与C也互相友好(在A的BFS中搜到了C)
那么C就直接染色。
但要不要判断B与C的关系了呢?应该不用了吧。
#include<stdio.h> using namespace std; longf[201][201],map[201][201],num[201],now[201],cnt,i,j,k,n; void dfs(long k) { long go,i; for (i=1;i<=num[k];i++) { go=map[k][i]; if (now[go]==0) { now[go]=cnt; dfs(go); } } } int main() { scanf("%ld",&n); for (i=1;i<=n;i++) { while (true) { scanf("%ld",&k); if (k==0) break; f[i][k]=true; } } for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if((i!=k)&&(i!=j)&&(j!=k)) f[i][j]=f[i][j]||f[i][k]&&f[k][j]; for (i=1;i<=n;i++) for (j=1;j<=n;j++) if((i!=j)&&(f[i][j]!=f[j][i])) { f[i][j]=false; f[j][i]=false; } for (i=1;i<=n;i++) { for (j=1;j<=n;j++) if (f[i][j]) { num[i]++; map[i][num[i]]=j; } now[i]=0; } cnt=0; for (i=1;i<=n;i++) if (now[i]==0) { cnt++;now[i]=cnt; dfs(i); } printf("%ld",cnt); }