HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)
Rank of Tetris
Time Limit: 1000/1000 MS (Java/Others)????Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9267????Accepted Submission(s): 2668
為了更好的符合那些愛好者的喜好,Lele又想了一個(gè)新點(diǎn)子:他將制作一個(gè)全球Tetris高手排行榜,定時(shí)更新,名堂要比福布斯富豪榜還響。關(guān)于如何排名,這個(gè)不用說都知道是根據(jù)Rating從高到低來排,如果兩個(gè)人具有相同的Rating,那就按這幾個(gè)人的RP從高到低來排。
終于,Lele要開始行動(dòng)了,對(duì)N個(gè)人進(jìn)行排名。為了方便起見,每個(gè)人都已經(jīng)被編號(hào),分別從0到N-1,并且編號(hào)越大,RP就越高。
同時(shí)Lele從狗仔隊(duì)里取得一些(M個(gè))關(guān)于Rating的信息。這些信息可能有三種情況,分別是"A > B","A = B","A < B",分別表示A的Rating高于B,等于B,小于B。
現(xiàn)在Lele并不是讓你來幫他制作這個(gè)高手榜,他只是想知道,根據(jù)這些信息是否能夠確定出這個(gè)高手榜,是的話就輸出"OK"。否則就請(qǐng)你判斷出錯(cuò)的原因,到底是因?yàn)樾畔⒉煌耆?#xff08;輸出"UNCERTAIN"),還是因?yàn)檫@些信息中包含沖突(輸出"CONFLICT")。
注意,如果信息中同時(shí)包含沖突且信息不完全,就輸出"CONFLICT"。
?
Input 本題目包含多組測(cè)試,請(qǐng)?zhí)幚淼轿募Y(jié)束。每組測(cè)試第一行包含兩個(gè)整數(shù)N,M(0<=N<=10000,0<=M<=20000),分別表示要排名的人數(shù)以及得到的關(guān)系數(shù)。
接下來有M行,分別表示這些關(guān)系
?
Output 對(duì)于每組測(cè)試,在一行里按題目要求輸出?
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?
題目鏈接:HDU 1811
題意:給定N個(gè)點(diǎn)和M個(gè)關(guān)系,可以使=、>或<的關(guān)系,求能否唯一確定這N個(gè)點(diǎn)的大小關(guān)系。
看到等于號(hào)=可以用并查集來處理把相等關(guān)系的點(diǎn)都縮一個(gè)點(diǎn),然后就是判斷這個(gè)縮點(diǎn)之后的圖是否是一個(gè)DAG,若不是DAG則說明是CONFLICT,否則再判斷是否是UNCERTAIN,如何判斷呢?用一個(gè)dis數(shù)組記錄拓?fù)渑判虺龅狞c(diǎn)距離起始點(diǎn)的層次關(guān)系,若存在兩個(gè)縮點(diǎn)的dis相同,則說明這兩個(gè)點(diǎn)關(guān)系不明確,或者存在某一個(gè)縮點(diǎn)它沒有出邊和入邊,且它的秩小于總點(diǎn)數(shù)N,說明這個(gè)集合被孤立出去,集合內(nèi)的點(diǎn)關(guān)系也是不明確的。當(dāng)然一開始得先離線處理縮點(diǎn),不然萬一輸入次序一變化,加的邊就不對(duì)了
給兩組數(shù)據(jù):
?
3 1
1 = 0
UNCERTAIN
2 1
1 = 0
OK
?
代碼:
#include <stdio.h> #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 10010; const int M = 20010; struct edge {int to, nxt;edge() {}edge(int _to, int _nxt): to(_to), nxt(_nxt) {} } E[N]; struct info {int a, b;char ops[3]; } rela[M];int head[N], tot; int in[N], out[N], pre[N], ran[N], cnt[N], vis[N], dis[N];void init() {CLR(head, -1);tot = 0;CLR(in, 0);CLR(out, 0);CLR(pre, -1);CLR(cnt, 0);CLR(vis, 0);CLR(dis, 0);fill(ran, ran + N, 1); } int Find(int n) {return pre[n] == -1 ? n : pre[n] = Find(pre[n]); } void joint(int a, int b) {a = Find(a);b = Find(b);if (a == b)return ;pre[a] = b;ran[b] += ran[a];ran[a] = 0; } inline void add(int s, int t) {E[tot] = edge(t, head[s]);head[s] = tot++; } int Top_sort1(int n) {queue<int>Q;int i;bool uncertain = false, conflict = false;for (i = 0; i < n; ++i){int fi = Find(i);if (!vis[fi] && !in[fi]){Q.push(fi);dis[fi] = 1;++cnt[dis[fi]];vis[fi] = 1;}if (!out[fi] && !in[fi] && ran[fi] < n)uncertain = true;}CLR(vis, 0);while (!Q.empty()){int u = Q.front();Q.pop();for (i = head[u]; ~i; i = E[i].nxt){int v = E[i].to;if (--in[v] == 0){Q.push(v);dis[v] = dis[u] + 1;if (!vis[v])++cnt[dis[v]];}}}for (i = 0; i < n; ++i){int fi = Find(i);if (in[fi]){conflict = true;break;}}for (i = 1; i <= n; ++i){if (cnt[i] >= 2){uncertain = true;break;}}if (conflict)return -1;else if (uncertain)return 0;return 1; } int main(void) {int n, m, i;while (~scanf("%d%d", &n, &m)){init();for (i = 0; i < m; ++i){scanf("%d %s %d", &rela[i].a, rela[i].ops, &rela[i].b);if (rela[i].ops[0] == '=')joint(rela[i].a, rela[i].b);}for (i = 0; i < m; ++i){if (rela[i].ops[0] == '=')continue;if (rela[i].ops[0] == '<')swap(rela[i].a, rela[i].b);int fa = Find(rela[i].a), fb = Find(rela[i].b);add(fa, fb);++in[fb];++out[fa];}int ans = Top_sort1(n);if (ans == 1)puts("OK");else if (ans == 0)puts("UNCERTAIN");elseputs("CONFLICT");}return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/Blackops/p/6653833.html
總結(jié)
以上是生活随笔為你收集整理的HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用正则表达式大全!
- 下一篇: 史上最快的拼接字串方法