题目要求排序是严格顺序的,即关系图是单connected component的,同时图中任一部分不能是环(只注意到了图整个是个环,忘记图中间可能有环,参考了这篇博客http://blog.youkuaiyun.com/ice_crazy/article/details/8330999才恍然大悟,WA了好几次,真是渣到爆……),题目的关键是相同rating的节点通过一个father节点来代表,这个father节点连接其代表的所有节点的边:
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
#define MAX_NODE_COUNT 10000
#define MAX_EDGE_COUNT 20000
int N, M;
vector<int> out[MAX_NODE_COUNT];//for node in out[i] has relation: i > node
int indegree[MAX_NODE_COUNT];//in degree of each node
struct Edge{
int x, y;
char c;
} edge[MAX_EDGE_COUNT];//all edges with relation description
int father[MAX_NODE_COUNT];//merge nodes with same rating into one, connecting all edges
int Find(int x)
{
return father[x] != x ? father[x] = Find(father[x]) : x;
}
void Union(int x, int y)
{
int px = Find(x), py = Find(y);
//for nodes with same rating, the one with larger ID is representive
if(px > py) father[py] = px;
else if(px < py) father[px] = py;
}
void init()
{
for(int i = 0; i < N; ++i){
out[i].clear();
indegree[i] = 0;
father[i] = i;
}
}
bool input()
{
if(scanf("%d %d", &N, &M) != 2) return false;
else init();
for(int i = 0; i < M; ++i){
scanf("%d %c %d", &edge[i].x, &edge[i].c, &edge[i].y);
if(edge[i].c == '=') Union(edge[i].x, edge[i].y);
}
return true;
}
inline void addOut(int from, int to)
{
out[from].push_back(to);
++indegree[to];
}
bool buildGraph()
{
int px, py;
for(int i = 0; i < M; ++i){
if(edge[i].c == '=') continue;
px = Find(edge[i].x);
py = Find(edge[i].y);
if(px == py) return false;//exist conflict circle such as a = c, b = c but a > b !!!
else if(edge[i].c == '>') addOut(px, py);
else addOut(py, px);
}
return true;
}
int topoSort()
{
queue<int> q;
int distinct = 0, ordered = 0, flag = 0;
for(int i = 0; i < N; ++i){
if(father[i] == i){//otherwise the node has been absorbed into other one
++distinct;
if(indegree[i] == 0) q.push(i);
}
}
if(q.empty()) return 1;//conflit circle such as a > b > c > a in total !!!
while(!q.empty()){
if(q.size() > 1) flag = 2;//there are nodes whose relative order is not certain !!!
int x = q.front(); q.pop();
++ordered;
const vector<int>& v = out[x];
for(int i = 0, n = v.size(); i < n; ++i){
if(--indegree[v[i]] == 0) q.push(v[i]);
}
}
return ordered != distinct ? 1 : flag;//there may exist conflit circle in middle !!!
//there may exist separate connected components !!!
}
int main()
{
while(input()){
if(!buildGraph()){
puts("CONFLICT");
continue;
}
switch(topoSort()){
case 1: puts("CONFLICT"); break;
case 2: puts("UNCERTAIN"); break;
default: puts("OK"); break;
}
}
return 0;
}