通过二分图染色 判断是否能划分成两个集合
/**********
对该题的思考 对于不相互认识 的 肯定 不相同的集合中(染色体现在 不相互认识的 染成 异色)
对于 相互认识的 不一定 在同一个集合中 (先不染色)
本题目通过 多次 排除 不相互认识的,
然后得到答案
*********************/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 150;
int G[maxn][maxn];
int vis[maxn];
int n;/***n个人***/
void init()/****初始化**/
{
memset(G, 0, sizeof(G));
}
void input()
{
int y;
for(int i = 1; i <= n; i++)
{
while(cin>>y&&y)
{
G[i][y] = 1;
}
}
}
bool bfs(int s, int c)
{
queue<int>q;
while(!q.empty())q.pop();
q.push(s);
vis[s] = c;
int x;
while(!q.empty())
{
x = q.front();
q.pop();
for(int y = 1; y <= n; y++)
{
if(y == x)continue;/**自己 对自己 跳过**/
if((G[x][y]&&G[y][x]))continue;/****如果 相互认识 跳过***/
/***********对于不认识 的 染成 异色****************/
if(vis[y] == 0)
{
vis[y] = vis[x] == 1?-1:1;
q.push(y);
}
/*******如果 不认识 且 颜色相同 就 false*****/
else if(vis[x] == vis[y])
{
return false;
}
}
}
return true;
}
int main()
{
while(cin>>n)
{
init();
input();
bool f = false;
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++)
{
if(vis[i] == 0)/****没有染色 的 放在集合 1中***/
{
if(!bfs(i, 1))
{
f = 1;
break;
}
}
}
if(!f)cout <<"YES"<<endl;
else cout <<"NO"<<endl;
}
return 0;
}