题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751
题目大意:判断一堆人能否分成两组,组内人都互相认识。
解题思路:如果两个人不是相互认识,该两人之间连边。最终构成一张图,二分匹配。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 #define maxn 105 6 #define maxm 20010 7 int n,e; 8 bool path[105][105],flag; 9 int first[maxn],next[maxm],v[maxm]; 10 int color[maxn]; 11 bool vis[maxn]; 12 void addedge(int x,int y) 13 { 14 v[e]=y; 15 next[e]=first[x]; 16 first[x]=e++; 17 } 18 bool solve(int x,int now,int from) 19 { 20 int i,k; 21 color[x]=now; 22 for(i=first[x];i!=-1;i=next[i]) 23 { 24 k=v[i]; 25 if(k!=from) 26 { 27 if(!color[k]) 28 { 29 if(solve(k,-now,x)==false)return false; 30 } 31 if(color[k]==color[x])return false; 32 } 33 } 34 vis[x]=true; 35 return true; 36 } 37 int main() 38 { 39 int L,i; 40 while(scanf("%d",&n)!=EOF) 41 { 42 memset(color,0,sizeof(color)); 43 memset(vis,false,sizeof(vis)); 44 memset(path,false,sizeof(path)); 45 for(i=1;i<=n;i++) 46 { 47 while(scanf("%d",&L),L) 48 path[i][L]=true; 49 } 50 memset(first,-1,sizeof(first)); 51 for(i = 1; i < n;i++) 52 { 53 for(int j=i+1;j<=n;j++) 54 { 55 if(!path[i][j]||!path[j][i]) 56 { 57 addedge(i,j); 58 addedge(j,i); 59 } 60 } 61 } 62 flag=true; 63 for(i=1;i<=n&&flag==true;i++) 64 if(color[i]==0){ 65 vis[i]=true;flag=solve(i,1,-1); 66 } 67 if(flag)printf("YES\n"); 68 else printf("NO\n"); 69 } 70 return 0; 71 }