题目链接:
题目大意:判断一堆人能否分成两组,组内人都互相认识。
解题思路:如果两个人不是相互认识,该两人之间连边。最终构成一张图,二分匹配。
1 #include2 #include 3 #include 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 }