http://acm.hdu.edu.cn/showproblem.php?pid=4751
题意:某人想举办一个活动,但他只能举办两次,要求每次参加的人都相互认识,求活动是否可以举办成功
分析:每次参加的人都是一个完全图,可以用染色法反向建图(从A开始,他认识且认识他的人在第一集合,他不认识的人都在第二集合,依次染色,检查是否可以形成一个二分图)
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
const int NM=105;
int a[NM][NM],col[NM],n;
bool Color()
{
int i,j,t;
memset(col,-1,sizeof(col));
for(i=1;i<=n;i++)
{
if(col[i]!=-1) continue;
col[i]=1;
queue<int>q1;
q1.push(i);
while(!q1.empty())
{
t=q1.front();q1.pop();
for(j=1;j<=n;j++)
{
if(j!=t&&!a[t][j]) //排除(自己+我认识-认识我)
{
if(col[j]==col[t]) return false;
if(col[j]==-1)
{
col[j]=1-col[t];
q1.push(j);
}
}
}
}
}
return true;
}
int main()
{
int i,j,y;
while(scanf("%d",&n)!=EOF)
{
memset(a,0,sizeof(a));
for(i=1;i<=n;i++)
{
while(scanf("%d",&y))
{
if(!y) break;
a[i][y]=1;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) //注意清除单向边
if(!a[i][j])
a[j][i]=0;
if(Color()) printf("YES\n");
else printf("NO\n");
}
return 0;
}