HDOJ1811 稍微复杂一点的拓扑排序应用

来源:互联网 发布:华讯网络 电科软信 编辑:程序博客网 时间:2024/06/01 09:46

Rank of Tetris

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10356 Accepted Submission(s): 2961

Problem Description
自从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

Author
linle

Source
HDOJ 2007 Summer Exercise(2)

Recommend
lcy | We have carefully selected several similar problems for you: 1198 1301 2094 1823 1809

很显然,等号关系是重点。
正解就是采用并查集,把rank相同的点合并在一起。
把图浓缩一下,判断时候再分为三种情况就好了。

我的c++功底显然还不够。。。
很多语法上的写法导致一些难以察觉的逻辑错误,调试了好久才AC。。。
不过总算是过了,觉得对自己能力提升还蛮大的。
毕竟才学了一个月的c++,不能苛求跟那些用了好多年的老手一样熟练。。

#include <iostream>#include <ctime>#include <cstring>#include <queue>using namespace std;const int maxn = 1e4+5;const int maxm = 2e4+5;int i,j,k,m,n,state,tot;int f[maxn],a[maxm],b[maxm];char c[maxm][5];struct Node{   int  head,in;}point[maxn];struct node{   int to,next;}edge[maxm];int Find(int x){    if (f[x]==-1) return x;    return f[x] = Find(f[x]);}void Merge(int x, int y){   int fx = Find(x), fy = Find(y);   if (fx!=fy) f[fx] = fy;}void init(){    for (i=0; i<=n; i++) {point[i].head = -1; point[i].in = 0; f[i]=-1;}    for (i=1; i<=m; i++) {         cin >> a[i] >> c[i] >> b[i];         if (c[i][0] == '=' ) Merge(a[i],b[i]);    }}int tuopu(){    queue<int>que;    int sum = 0,u,v,root_num = 0;    bool flag = 1;    for (k=0; k<n; k++) if (Find(k)==k) {            root_num++;            if (point[Find(k)].in==0) que.push(Find(k));    }    while (!que.empty()){        if (que.size()>1) flag = 0;        u = que.front();        que.pop();        sum++;        for (k = point[u].head; k!=-1; k=edge[k].next) {             v = edge[k].to;             if (--point[Find(v)].in==0) que.push(Find(v));        }    }    if (sum<root_num) return -1;    if (flag) return 1;    return 0;}void add_edge(int u, int v) {       edge[tot].next = point[u].head;       point[u].head = tot;       edge[tot].to = v;       point[v].in++;       tot++;}int main(){    std::ios::sync_with_stdio(false);    while (cin >> n >> m){            init();            state = 0;            tot = 0;            for (i=1; i<=m; i++) {                 if (Find(a[i])==Find(b[i]) && c[i][0]!='=') {state=-1; break;}                 if (c[i][0]=='>') add_edge(Find(a[i]),Find(b[i]));                 if (c[i][0]=='<') add_edge(Find(b[i]),Find(a[i]));            }            if (state==0) state = tuopu();            if (state==-1) cout << "CONFLICT" << endl;            else if (state== 1) cout << "OK" << endl;            else  cout << "UNCERTAIN" << endl;    }    return 0;}
原创粉丝点击