首先,列举几种常见的Wrong Answer的数据
第一种
2 5
0 > 1
1 < 0
0 = 1
0 =1
1 = 0
第二种
3 3
0 = 1
1 > 2
2 < 0
第三种
5 0
第三种数据应该是uncertain
如果是排名是相同的人,用并查集合并
然后再检测是否有环即可。
下附AC代码:
/*HDOJ 1811
作者:陈佳润
2013-04-29*/
#include<iostream>
#include<queue>
using namespace std;
typedef struct tag1{//节点
int son;
struct tag1 *next;
}Node;
typedef struct tag2{/邻接表
int num;
Node * list;
}List;
List L[10005];
int father[10005];
int a[10005],b[10005];
char c[10005];
queue<int>Q;
int find(int x);//查询父节点
void Merge(int a,int b);//合并
void Insert(int a,int b);//将节点插入邻接表
int main(){
int n,m,N,i,flag,sum;
while(cin>>n>>m){
//初始化
for(i=0;i<n;i++){
L[i].num=0;
L[i].list=NULL;
father[i]=i;
}
for(i=0;i<m;i++){//读取数据,利用并查集合并
scanf("%d %c %d",&a[i],&c[i],&b[i]);
if(c[i]=='='){
Merge(a[i],b[i]);
}
}
//构造表
for(i=0;i<m;i++){
if(c[i]=='=')
continue;
if(c[i]=='>')
Insert(a[i],b[i]);
else
Insert(b[i],a[i]);
}
//拓扑排序
for(i=0;i<n;i++){//第一批前驱节点入队列
if(L[i].num==0 && i==find(i))
Q.push(i);
}
for(i=0,N=0;i<n;i++){//统计父节点数量
if(i==find(i))
N++;
}
flag=0;
sum=0;
while(Q.size()){
if(Q.size()>1) flag=1;//UNCERTAIN
int t=Q.front();
Q.pop();
sum++;
while(L[t].list){
L[L[t].list->son].num--;
if(L[L[t].list->son].num==0)
Q.push(L[t].list->son);
L[t].list=L[t].list->next;
}
}
if(sum<N)
cout<<"CONFLICT"<<endl;
else if(flag)
cout<<"UNCERTAIN"<<endl;
else
cout<<"OK"<<endl;
}
return 0;
}
//---------------------------------------------
int find(int x){
int t;
if(father[x]==x)
return x;
t=find(father[x]);
father[x]=t;
return t;
}
void Merge(int a,int b){
a=find(a);
b=find(b);
father[a]=b;
}
void Insert(int a,int b){
Node *p=new Node;
a=find(a);
b=find(b);
L[b].num++;
p->son=b;
p->next=L[a].list;
L[a].list=p;
}