题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751
题目大意:判断一堆人能否分成两组,组内人都互相认识。
解题思路:如果两个人不是相互认识,该两人之间连边。最终构成一张图,二分匹配。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 105
#define maxm 20010
int n,e;
bool path[][],flag;
int first[maxn],next[maxm],v[maxm];
int color[maxn];
bool vis[maxn];
void addedge(int x,int y)
{
v[e]=y;
next[e]=first[x];
first[x]=e++;
}
bool solve(int x,int now,int from)
{
int i,k;
color[x]=now;
for(i=first[x];i!=-;i=next[i])
{
k=v[i];
if(k!=from)
{
if(!color[k])
{
if(solve(k,-now,x)==false)return false;
}
if(color[k]==color[x])return false;
}
}
vis[x]=true;
return true;
}
int main()
{
int L,i;
while(scanf("%d",&n)!=EOF)
{
memset(color,,sizeof(color));
memset(vis,false,sizeof(vis));
memset(path,false,sizeof(path));
for(i=;i<=n;i++)
{
while(scanf("%d",&L),L)
path[i][L]=true;
}
memset(first,-,sizeof(first));
for(i = ; i < n;i++)
{
for(int j=i+;j<=n;j++)
{
if(!path[i][j]||!path[j][i])
{
addedge(i,j);
addedge(j,i);
}
}
}
flag=true;
for(i=;i<=n&&flag==true;i++)
if(color[i]==){
vis[i]=true;flag=solve(i,,-);
}
if(flag)printf("YES\n");
else printf("NO\n");
}
return ;
}