并查集 + 拓扑排序。
拓扑排序具体怎么用还要学习,这个题里面就是从入度为零开始算起。一次只有一个入度为零,若大于一,则UNCERTAIN 如果执行完毕,还有数字没被计算,那么有环,则CONFLICT;
#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 10000 + 5;
struct node
{
int a,b;
char op;
} ship[maxn];
int pre[maxn];
vector<int> u[maxn];
int in[maxn];
int n, m, sum;
void init()
{
sum = n;
for(int i = 0; i <= n; i++)
u[i].clear();
for(int i = 0; i <= n; i++)
pre[i] = i;
memset(in, 0, sizeof(in));
}
int root(int x)
{
if(x != pre[x])
pre[x] = root(pre[x]);
return pre[x];
}
int merge_set(int x, int y)
{
int fx = root(x);
int fy = root(y);
if(fx == fy) return false;
else
{
pre[fx] = fy;
return true;
}
}
void top_sort()
{
int little = false;
queue<int> q;
for(int i = 0; i < n; i++)
{
if(pre[i] == i && !in[i])
q.push(i);
}
while(!q.empty())
{
if(q.size() > 1) little = true;
int t = q.front();
sum--;
q.pop();
for(int i = 0; i < u[t].size(); i++)
{
in[u[t][i]]--;
if(in[u[t][i]] == 0)
{
q.push(u[t][i]);
}
}
}
if(sum > 0) printf("CONFLICT\n");
else if(little) printf("UNCERTAIN\n");
else printf("OK\n");
}
int main()
{
while(scanf("%d%d", &n, &m) == 2)
{
init();
for(int i = 0; i < m; i++)
{
scanf("%d %c %d", &ship[i].a, &ship[i].op, &ship[i].b);
if(ship[i].op == '=')
{
if(merge_set(ship[i].a, ship[i].b))
sum--;
}
}
for(int i = 0; i < m; i++)
if(ship[i].op != '=')
{
int f = root(ship[i].a), s = root(ship[i].b);
if(ship[i].op == '>')
{
u[f].push_back(s);
in[s]++;
}
else
{
u[s].push_back(f);
in[f]++;
}
}
top_sort();
}
return 0;
}