【HDU - 1811 Rank of Tetris】 並查集+拓撲排序

B - Rank of Tetris

自從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


題意:對於給定的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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章