(拓扑排序+并查集)HDU - 1811 Rank of Tetris

Posted tak_fate

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(拓扑排序+并查集)HDU - 1811 Rank of Tetris相关的知识,希望对你有一定的参考价值。

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1811


 

题意:有个很多关系,现在需要产生一个名单,有的人比有的人牛逼,有的人没有的人牛逼,有的人一样牛逼,现在需要通过牛逼程度排名,如果1比2牛逼,1的排名就比2前,如果1和2一样牛逼,就比两个人的人品,人品好的人排前面。

现在有三种情况:

1、正确

2、矛盾

3、无法确定


分析:

这里其他方面还是比较简单。首先确定三种情况的发生条件:

矛盾--存在环,也就是在toposort之后,没有把所有的点全都访问到。

无法确定--只要存在一次入度为0的点不止一个,那么这个拓扑序就不唯一,所以无法确定。


代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <string>
  4 #include <vector>
  5 #include <map>
  6 #include <set>
  7 #include <queue>
  8 #include <cstring>
  9 #include <algorithm>
 10 
 11 using namespace std;
 12 
 13 
 14 typedef long long ll;
 15 typedef unsigned long long ull;
 16 #define inf (0x3f3f3f3f)
 17 #define lnf (0x3f3f3f3f3f3f3f3f)
 18 #define eps (1e-8)
 19 int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1 ;}
 20 
 21 //-------------------------------------------------
 22 
 23 
 24 const int maxn=10010;
 25 vector<int> edge[maxn];
 26 
 27 int indu[maxn];
 28 int par[maxn];
 29 int ranks[maxn];
 30 int u[maxn],v[maxn];
 31 int n,m;
 32 int rn;
 33 char op[maxn][3];
 34 
 35 void init(){
 36     for(int i=0;i<n;i++){
 37         par[i]=i;
 38         ranks[i]=0;
 39         edge[i].clear();
 40     }
 41     memset(indu,0,sizeof(indu));
 42 }
 43 
 44 int findx(int x){
 45     if(par[x]==x)return x;
 46     else return par[x]=findx(par[x]);
 47 }
 48 
 49 bool unite(int x,int y){
 50     x=findx(x);
 51     y=findx(y);
 52     if(x==y)return false;
 53     if(ranks[x]>ranks[y]){
 54         par[y]=x;
 55     }
 56     else{
 57         if(ranks[x]==ranks[y]){
 58             ranks[y]++;
 59         }
 60         par[x]=y;
 61     }
 62     return true;
 63 }
 64 
 65 
 66 bool toposort(){
 67     queue<int> q;
 68     for(int i=0;i<n;i++){
 69         if(indu[i]==0&&i==findx(i)){
 70             indu[i]--;
 71             q.push(i);
 72         }
 73     }
 74     bool allon=false;
 75 
 76     while(!q.empty()){
 77         if(q.size()>1)allon=true;
 78         int u=q.front();
 79         q.pop();
 80         rn--;
 81         for(int i=0;i<edge[u].size();i++){
 82             indu[edge[u][i]]--;
 83             if(indu[edge[u][i]]==0){
 84                 q.push(edge[u][i]);
 85             }
 86         }
 87     }
 88     return allon;
 89 }
 90 
 91 
 92 void solve(){
 93     while(~scanf("%d%d",&n,&m)){
 94         init();
 95         rn=n;
 96         for(int i=0;i<m;i++){
 97             scanf("%d%s%d",&u[i],op[i],&v[i]);
 98             if(op[i][0]===){
 99                 if(unite(u[i],v[i])){
100                     rn--;
101                 }
102             }
103         }
104         for(int i=0;i<m;i++){
105             if(op[i][0]!==){
106                 int x=findx(u[i]);
107                 int y=findx(v[i]);
108                 if(op[i][0]==>){
109                     edge[x].push_back(y);
110                     indu[y]++;
111                 }
112                 else{
113                     edge[y].push_back(x);
114                     indu[x]++;
115                 }
116             }
117         }
118         bool allon=toposort();
119         if(rn>0){
120             puts("CONFLICT");
121         }        
122         else if(allon){
123             puts("UNCERTAIN");
124         }
125         else{
126             puts("OK");
127         }
128     }
129 
130 }
131 
132 
133 
134 int main(){
135 
136 #ifndef ONLINE_JUDGE
137     freopen("1.in","r",stdin);
138     //freopen("1.out","w",stdout);
139 #endif
140 
141     solve();
142 }

 

以上是关于(拓扑排序+并查集)HDU - 1811 Rank of Tetris的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1811:Rank of Tetris(并查集+拓扑排序)

HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)

HDU 1811 Rank of Tetris(拓扑排序+并查集)

hdu1811 Rank of Tetris 并查集+拓扑排序

HDU 1811 Rank of Tetris(并查集按秩合并+拓扑排序)

(拓扑排序+并查集)HDU - 1811 Rank of Tetris