这道题WA了两天 - - !
思路:首先分析以下什么情况下才能OK(当然时可以判断出顺序的情况下),
CONFLICT(1就是存在等号并且有再>或<下情况存在所以一定时冲突的,2在开始统计并将度为0的点进入队列,同时要判断一下i==f[i]的点的个数,是否和即将全部出队列的个数一致);
UNCERTAIN(当入度为0 的个数>1{其中有两部分1,在开始压队列的时候判断一次,2再队列中删除度后再判断一次} )
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<algorithm>
#include<queue>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int cnt;
struct node
{
int to,next;
} q[20010];
int l[20010],r[20010];
char s[20010];
int du[20010],head[20010],f[20010];
int n,m;
int fi(int x)
{
return x==f[x]?x:f[x]=fi(f[x]);
}
void mer(int a,int b)
{
int x=fi(a);
int y=fi(b);
f[x]=y;
}
void add(int x,int y)
{
q[cnt].to=y;
q[cnt].next=head[x];
head[x]=cnt++;
}
int topo()
{
int j,k,i;
queue<int >Q;
int tot,tmp,flag;
tot=tmp=flag=0;
for(i=0;i<n;i++)
{
if(i==f[i])
{
tot++;
if(!du[i])
{
tmp++;
Q.push(i);
}
if(tmp>1)
flag=2;
}
}
k=0;
while(!Q.empty())
{
int t=Q.front();
Q.pop();
k++;
//du[t]--;
tmp=0;
for(j=head[t];j!=-1;j=q[j].next)
{
du[ q[j].to ]--;
if(!du[q[j].to ])
{
tmp++;
Q.push(q[j].to);
}
}
if(tmp>1)
flag=2;
}
if(k<tot)
flag=1;
return flag;
}
int Map()
{
int i,x,y;
for(i=0;i<n;i++)
f[i]=i;
for(i=0;i<m;i++)
{
scanf("%d %c %d",&l[i],&s[i],&r[i]);
if(s[i]=='=')
{
x=fi(l[i]);
y=fi(r[i]);
f[x]=y;
}
}
memset(head,-1,sizeof(head));
memset(du,0,sizeof(du));
cnt=0;
for(i=0;i<m;i++)
{
if(s[i]=='=')
continue;
x=fi(l[i]);
y=fi(r[i]);
if(x==y)
return 1;
if(s[i]=='>')
{
add(x,y);
du[y]++;
}
else if(s[i]=='<')
{
add(y,x);
du[x]++;
}
}
return 0;
}
int main()
{
int i,j,k,ans;
while(~scanf("%d %d",&n,&m))
{
ans=Map();
if(ans)
{
printf("CONFLICT\n");continue;
}
ans=topo();
if(!ans)
puts("OK");
else if(ans == 1)
puts("CONFLICT");
else
puts("UNCERTAIN");
}
return 0;
}