题目:
http://acm.hdu.edu.cn/showproblem.php?pid=4751题意:
n个人之间有互相认识的关系,问是否能把所有人分成两份,使每份中的所有人之间互相认识。思路:
就是把一个有向图分成两个完全图。可以逆向考虑,既然要分成两个图又是完全图,反过来就是一个二分图,把不认识标记为边,互相认识是没有边,也就是一个标准的二分图了,然后染色判断二分图就行了。代码:
#define N 112
int n,m;
int flag,sum,ave,ans,res,len,ans1,ans2,cnt;
int mapp[N][N],f[N];
vector<int>g[N];
void init()
{
cnt = 0;
memset(f,-1,sizeof(f));
for(int i=0;i<=n;i++)
g[i].clear();
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
mapp[i][j]=mapp[j][i]=1;
}
void inserts(int u, int v)
{
g[u].push_back(v);
g[v].push_back(u);
}
void dye(int u)
{
int v;
for(int i=0;i<g[u].size();i++)
{
v = g[u][i];
if(f[v]==f[u])
flag=0;
if(f[v]!=-1)
continue;
f[v] = f[u]^1;
dye(v);
}
}
void Dye()
{
for(int i=1;i<=n;i++)
if(f[i] == -1)
{
f[i] = 0;
dye(i);
}
}
int main()
{
int i,j,k,kk,t,x,y,z;
while(scanf("%d",&n)!=EOF&&n)
{
init();
for(i=1;i<=n;i++)
while(scanf("%d",&t)&&t)
mapp[i][t]=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(mapp[i][j]&&i!=j)
inserts(i,j);
flag=1;
Dye();
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}