此题是一个并查集与拓扑排序结合的题
1.把相等的点并合为一个集
2.统计合并后总共有几个点
3.通过拓扑排序来判断属于那种情况:若又一次S.size()>1,则说明不确定;若cnt<num则存在环路;以上两种情况都不存在则说明ok
#include<iostream>
#include<vector>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 10010
typedef struct Point
{
int x,y;
}Point;
Point p[maxn];
vector<int>p_link[maxn];
int bin[maxn],index[maxn];
int n;
int find(int x)
{
while(x!=bin[x]) x=bin[x];
return x;
}
void TopologicalSort()
{
int i,u,v,num=0,cnt=0,flag=0;
stack<int>S;
for(i=0;i<n;i++)/////统计不想等的个数
{
if(bin[i]!=i) continue;
num++;
if(index[i]==0) S.push(i);///////统计度数为零的点
}
while(!S.empty())
{
if(S.size()>1) flag=1;
u=S.top(),S.pop(),cnt++;
for(i=0;i<p_link[u].size();i++)
{
v=p_link[u][i];
if(--index[v]==0) S.push(v);
}
}
if(cnt<num) printf("CONFLICT\n");//////存在回路矛盾
else if(flag) printf("UNCERTAIN\n");
else printf("OK\n");
}
int main()
{
int m,i;
char ch[2];
while(scanf("%d%d",&n,&m)==2)
{
int cnt=0,x,y;
memset(index,0,sizeof(index));
for(i=0;i<n;i++) p_link[i].clear(),bin[i]=i;
for(i=1;i<=m;i++)
{
scanf("%d%s%d",&x,&ch,&y);
if(ch[0]=='>')
p[cnt].x=x,p[cnt++].y=y;
else if(ch[0]=='<')
p[cnt].x=y,p[cnt++].y=x;
else/////////////把相等的合并在一起
{
x=find(x); y=find(y);
if(x>y)
bin[y]=x;
else
bin[x]=y;
}
}
for(i=0;i<cnt;i++)
{
x=find(p[i].x);
y=find(p[i].y);
index[y]++;
p_link[x].push_back(y);
}
TopologicalSort();
}
return 0;
}