爲了更好的符合那些愛好者的喜好,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"。
每組測試第一行包含兩個整數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 < 1Sample Output
OK CONFLICT UNCERTAIN
題意:對於給定的n(0~n-1)個數,有m組大小關係,問對於給定的關係能否得出正確的排序,如果滿足,輸出OK,如果條件不夠使其確定,輸出UNCERTAIN,如果所給條件衝突,輸出CONFLICT。
分析:一道拓撲排序,但是要注意把符號是“=”號的情況特殊處理,將“=”的組併爲一個集合,其他點正常處理,然後加邊。找到入度爲0且father[i] == i的點入隊,並且記錄father[i] == i的點的個數sum,如果入隊的點大於1,則說明情況不唯一(UNCERTAIN)。如果各點連邊成環,則衝突(CONFLICT),否則就滿足條件(OK)。
代碼如下:
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <vector>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mod 835672545
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MX = 2e4 + 5;
int n, m, tot;
int a[MX], b[MX];
char c[MX];
int in[MX];
int head[MX];
int father[MX];
struct node{
int v, nxt;
}e[MX];
void init(){
tot = 0;
memset(head, -1, sizeof(head));
memset(in, 0, sizeof(in));
for(int i = 0; i < n; i++){
father[i] = i;
}
}
void add(int u, int v){
e[tot].v = v;
e[tot].nxt = head[u];
head[u] = tot++;
}
int find(int x){
if(x != father[x]){
father[x] = find(father[x]);
}
return father[x];
}
int main(){
while(~scanf("%d%d", &n, &m)){
init();
for(int i = 0; i < m; i++){
scanf("%d %c %d", &a[i], &c[i], &b[i]);
if(c[i] == '='){
int x = find(a[i]);
int y = find(b[i]);
father[y] = x;
}
}
for(int i = 0; i < m; i++){
if(c[i] == '=') continue;
int x = find(a[i]);
int y = find(b[i]);
if(c[i] == '>'){
add(x, y);
in[y]++;
}
else{
add(y, x);
in[x]++;
}
}
queue<int> q;
int sum = 0;
for(int i = 0; i < n; i++){
if(find(i) == i) sum++;
if(in[i] == 0 && find(i) == i) q.push(i);
}
int flag = 0, cnt = 0;
while(!q.empty()){
++cnt;
if(q.size() > 1) flag = 1;
int u = q.front();
q.pop();
for(int i = head[u]; ~i; i = e[i].nxt){
int v = e[i].v;
in[v]--;
if(in[v] == 0) q.push(v);
}
}
if(cnt < sum) printf("CONFLICT\n");
else if(flag) printf("UNCERTAIN\n");
else printf("OK\n");
}
return 0;
}