一个人就是弱···做这个题做了四个小时···一直WA开始以为两个动态数组当作两个组,依次把每个人加入就好,还真觉得没什么问题。。。思维好搓啊,哪里可以这么简单。后面下来才知道这是一个tow_sat问题,第一次听说这个名词···,大概和二分图差不多,既然要分组,那么不认识的肯定不能在同一组,用两个标记进行排斥分组就好,但得注意此处的单方认识也要当作不认识,后面枚举每个点进行一遍dfs()查找是否有矛盾就好,这是很基础的一个模型,要好好体会这种思想。
#include<cstdio>
#include<cstring>
int G[105][105];
int color[105];
int n;
int dfs(int x){
for(int i=1;i<=n;i++){
if(G[x][i]||x==i)continue;
if(color[i]!=0&&color[i]==color[x])return 0;//如果出现矛盾就返回0代表不可能
else{
color[i]=0-color[x];//由于不认识就得染上不同颜色
if(!dfs(i))return 0;//继续dfs
}
}
return 1;
}
int main(){
while(scanf("%d",&n)!=EOF){
int u;
memset(G,0,sizeof(G));
memset(color,0,sizeof(color));
for(int i=1;i<=n;i++)
while(scanf("%d",&u)&&u)G[i][u]=1;
//单方认识在这里也算互不认识
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)if(G[i][j]&&!G[j][i])
{ G[i][j]=G[j][i]=0; }
int i;
for(i=1;i<=n;i++){
if(color[i]!=0)continue;
color[i]=1;//既然是最初的分组或者是朋友就可以分在这个组里面
if(!dfs(i))break;
}
if(i>n)printf("YES\n");
else printf("NO\n");
}
return 0;
}