拖了一年才开始写这个题。。。
实际上是2-SAT模型问题,当初的想法整个就错了,我原先是遍历,如果A认识B,就将B放到A的那个集合中,实际上,如果B和另一组的C也认识,B也可以放在C的那一组(取决于B和两组中其他成员的认识程度)。
所以这个问题要从反面入手,要看不认识的人能不能分在两个组中。
#include<iostream> #include<stdio.h> #include<cstdio> #include<stdlib.h> #include<vector> #include<string> #include<cstring> #include<cmath> #include<algorithm> #include<stack> #include<queue> #include <ctype.h> using namespace std; //hdu 4751 const int maxn=110; int mp[maxn][maxn]; int g[maxn][maxn];//interference graph int n; int color[maxn]; bool dfs(int u,int pre,int state)//different state means different groups { color[u]=state; for(int i=1;i<=n;i++) { if(g[u][i]) { int v=i; // if(v==pre) continue;//防止重复染色,比如pre将u染成1,u再将pre染成2就回到原先的状态,重复了,但是没有这一句也可以AC。。 // cout<<u<<" "<<v<<" "<<color[u]<<" "<<color[v]<<endl; if(color[v]&&color[u]==color[v]) { return false; } else { if(color[v]==0&&dfs(v,u,3-state)==false) return false; } } } return true; } int main() { freopen("input.txt","r",stdin); // freopen("data.txt","r",stdin); // freopen("out1.txt","w",stdout); while(scanf("%d",&n)!=EOF) { memset(mp,0,sizeof(mp)); memset(g,0,sizeof(g)); memset(color,0,sizeof(color)); for(int i=1;i<=n;i++) { while(true) { int c; scanf("%d",&c); if(c==0) break; else { mp[i][c]=1; } } } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(mp[i][j]==1&&mp[j][i]==1) continue; g[i][j]=g[j][i]=1;//两个人不是相互认识,不可放在一组 } } int flg=0; for(int i=1;i<=n;i++) { if(color[i]==0) { flg=dfs(i,i,1);//没有染过色,说明和之前的i认识,所以都染成1 // cout<<flg<<" "<<i<<endl; if(flg==0) { printf("NO\n"); break; } } } if(flg) { printf("YES\n"); } } return 0; }