自從Lele開發了Rating系統,他的Tetris事業更是如虎添翼,不久他遍把這個遊戲推向了全球。
爲了更好的符合那些愛好者的喜好,Lele又想了一個新點子:他將製作一個全球Tetris高手排行榜,定時更新,名堂要比福布斯富豪榜還響。關於如何排名,這個不用說都知道是根據Rating從高到低來排,如果兩個人具有相同的Rating,那就按這幾個人的RP從高到低來排。
終於,Lele要開始行動了,對N個人進行排名。爲了方便起見,每個人都已經被編號,分別從0到N-1,並且編號越大,RP就越高。
同時Lele從狗仔隊裏取得一些(M個)關於Rating的信息。這些信息可能有三種情況,分別是”A > B”,”A = B”,”A < B”,分別表示A的Rating高於B,等於B,小於B。
現在Lele並不是讓你來幫他製作這個高手榜,他只是想知道,根據這些信息是否能夠確定出這個高手榜,是的話就輸出”OK”。否則就請你判斷出錯的原因,到底是因爲信息不完全(輸出”UNCERTAIN”),還是因爲這些信息中包含衝突(輸出”CONFLICT”)。
注意,如果信息中同時包含衝突且信息不完全,就輸出”CONFLICT”。
Input
本題目包含多組測試,請處理到文件結束。
每組測試第一行包含兩個整數N,M(0<=N<=10000,0<=M<=20000),分別表示要排名的人數以及得到的關係數。
接下來有M行,分別表示這些關係
Output
對於每組測試,在一行裏按題目要求輸出
Sample Input
3 3
0 > 1
1 < 2
0 > 2
4 4
1 = 2
1 > 3
2 > 0
0 > 1
3 3
1 > 0
1 > 2
2 < 1
Sample Output
OK
CONFLICT
UNCERTAIN
給你一些編號的大小關係,問你能否對所有的編號排出大小順序,如果能輸出OK,如果給出的關係自相矛盾輸出CONFLICT,如果信息不全輸出UNCERTAIN. 如果僅有大於小於的話: 對於一種關係建立有向圖,然後進行拓撲排序,每次入度爲0的點入隊,如果隊中大於一個點,說明這些點之間沒有邊,即這些點不能判斷大小,信息不全。如果發現有環,說明衝突。
加上等於關係,如果還像原來一樣,一個數等於另一個數,那樣需要找到另一個數和其他數的大小關係,然後用這個數建邊,這樣就會非常麻煩,這裏我們把所有的相等的點選出一個點來代替他們(即並查集),點的總數相應減少就可以了
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
using namespace std;
#define maxn 11000
#define maxm 21000
int n,m;
int head[maxn],pre[maxn],indeg[maxn],vis[maxn];
char s[maxm];
int a[maxm],b[maxm];
int tot;
struct Edge
{
int to,next;
} edge[maxm];
int findroot(int num)
{
while(pre[num] != num)
{
num = pre[num];
}
return pre[num];
}
void add(int u,int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
indeg[v]++;
}
int topo()
{
queue<int>q;
int ans = 1;
int num = 0;
int block = 0;
for(int i = 0; i < n; i++)
{
if(findroot(i) == i)
{
block++;
}
}
for(int i = 0; i < n; i++)
{
int temp = findroot(i);
if(indeg[temp] == 0 &&vis[temp] == 0)
{
q.push(temp);
vis[temp] = 1;
}
}
while(!q.empty())
{
if(q.size() >= 2)
{
ans = -1;
}
int temp = q.front();
q.pop();
num++;
for(int i = head[temp]; i != -1; i = edge[i].next)
{
int x = findroot(edge[i].to);
indeg[x]--;
if(indeg[x] == 0 && vis[x] == 0)
{
q.push(x);
vis[x] = 1;
}
}
}
if(num < block) ans = 0;//衝突
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
tot = 0;
int ans = 4;
memset(head,-1,sizeof(head));
memset(indeg,0,sizeof(indeg));
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
{
pre[i] = i;
}
for(int i = 0; i < m; i++)
{
scanf("%d %c%d",&a[i],&s[i],&b[i]);
if(s[i] == '=')
{
int roota = findroot(a[i]);
int rootb = findroot(b[i]);
if(roota != rootb)
{
pre[roota] = rootb;
}
}
}
for(int i = 0; i < m; i++)
{
int u = findroot(a[i]), v = findroot(b[i]);
if(u == v && s[i] != '=')
{
ans = 0;
break;
}
if(s[i] == '<') add(u,v);
if(s[i] == '>') add(v,u);
}
if(ans != 0)
ans = topo();
if(ans == 1) printf("OK\n");
if(ans == -1) printf("UNCERTAIN\n");
if(ans == 0) printf("CONFLICT\n");
}
}