# include <stdio.h>
# include <algorithm>
# include <queue>
# include <iostream>
using namespace std;
int father[10010],r[20005],l[20005],into[10010],n;
char ch[20005];
int find(int x)
{
if(x==father[x])
return x;
return father[x]=find(father[x]);
}
struct node
{
int son;//儿子编号
node *next;//指向下个儿子,即为son的兄弟
};
struct node *N[10005];
void insert(int a,int b)//b插入作为a的儿子
{
node *p=new node;
p->son=b;
p->next=N[a];
N[a]=p;
}
void init()//初始化
{
int i;
for(i=0;i<n;i++)
{
father[i]=i;
into[i]=0;
N[i]=NULL;//指针
}
}
int main()
{
int i,num,m,a,b,flag;
while(~scanf("%d%d",&n,&m))
{
init();
num=n;
for(i=0;i<m;i++)
{
scanf("%d%s%d",&l[i],&ch[i],&r[i]);
if(ch[i]=='=')
{
a=find(l[i]);
b=find(r[i]);
if(a!=b)//合并成一个点
{
father[a]=b;
num--;//
}
}
}
flag=0;
for(i=0;i<m;i++)
{
if(ch[i]=='=')//上面已处理过
continue;
a=find(l[i]);
b=find(r[i]);
if(a==b)//上面已经处理过等于情况,应属于同个父亲节点,现在不等,矛盾 直接break
{
flag=1;
break;
}
if(ch[i]=='>')
{
insert(a,b);
into[b]++;
}
else
{
insert(b,a);
into[a]++;
}
}
if(flag)
{
printf("CONFLICT\n");//矛盾
continue;
}
queue<int>q;
for(i=0;i<n;i++)
if(into[i]==0&&i==find(i))
q.push(i);//拓扑排序后的终极父亲,入度为0,且为集合根节点
while(!q.empty())
{
if(q.size()>1)//有多个终极父亲~ 矛盾
flag=1;
num--;
int t=q.front();
q.pop();
for(node *i=N[t];i;i=i->next)
{
if(--into[i->son]==0)//入度为1才可入队列,为了防止重复入队列,自减
q.push(i->son);
}
}
if (num > 0) //根据题意,优先判断是否矛盾
puts ("CONFLICT");
else if (flag) //有多个拓扑排序序列,所以不确定
puts ("UNCERTAIN");
else
puts ("OK");
}
return 0;
}
HDU 1811 Rank of Tetris
最新推荐文章于 2021-08-04 00:09:59 发布