先用并查集把相等的情况合并了
再使用拓扑排序找冲突
具体是用大的数向小的数建边,然后判断冲突
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
const int MAX = 10005;
const int MAXM = 20005;
int f[MAX], n, m, cnt;
int d[MAX], tp, sz, to, sum;
int g[MAX], l[MAX];
vector<int> tag[MAX];
void init() {
cnt = 0, sum = n;
memset(d, 0, sizeof(d));
for(int i = 0; i <= n; ++i)
f[i] = i, tag[i].clear();
}
int find(int x) {
return x == f[x] ? x : f[x] = find(f[x]);
}
bool uni(int a, int b) {
int fa = find(a), fb = find(b);
if(fa == fb)
return false;
f[fa] = fb;
return true;
}
void topsort(){
queue<int> q;
for(int i = 0; i < sum; ++i)
if(!d[i] && find(i) == i)
q.push(i);
bool flag = false;
while(!q.empty()){
if(q.size() > 1){
flag = true;
}
tp = q.front();
q.pop(), n --;
sz = tag[tp].size();
for(int i = 0; i < sz; ++i) {
to = tag[tp][i];
d[to] --;
if(!d[to])
q.push(to);
}
}
if(n)
puts("CONFLICT");
else if(flag)
puts("UNCERTAIN");
else
puts("OK");
}
int main() {
char c[2];
int a, b;
while(~scanf("%d%d", &n, &m)){
init();
while(m --) {
scanf("%d%s%d", &a, c, &b);
if(c[0] == '='){
if(uni(a, b))
n --;
}
else if(c[0] == '>') {
g[cnt] = a, l[cnt ++] = b;
}
else {
l[cnt] = a, g[cnt ++] = b;
}
}
for(int i = 0; i < cnt; ++i) {
tag[find(g[i])].push_back(find(l[i]));
d[find(l[i])] ++;
}
topsort();
}
return 0;
}