当初网络赛的时候只想到了2-sat方法,后来想想,哪要这么麻烦啊,随便染个色,证明一下是二分图不就完了么。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,a;
int fst[105],next[20005],node[20005],en;
bool vis[105];
int c[105],ans;
bool p[105][105];
void init()
{
en=0;
ans=0;
memset(fst,-1,sizeof(fst));
memset(vis,0,sizeof(vis));
memset(p,0,sizeof(p));
}
void add(int u,int v)
{
next[en]=fst[u];
fst[u]=en;
node[en]=v;
en++;
next[en]=fst[v];
fst[v]=en;
node[en]=u;
en++;
}
void bfs(int s)
{
queue<int>q;
q.push(s);
vis[s]=1;
c[s]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=fst[u];i!=-1;i=next[i])
{
int v=node[i];
if(!vis[v])
{
vis[v]=1;
c[v]=!c[u];
q.push(v);
}
else if(c[u]==c[v])ans=1;
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=1;i<=n;i++)
{
while(scanf("%d",&a))
{
if(a==0)break;
p[i][a]=1;
}
}
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(p[i][j]&&p[j][i])continue;
add(i,j);
add(j,i);
}
}
for(int i=1;i<=n;i++)
{
if(!vis[i])bfs(i);
}
if(ans==1)cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
}