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

Posted 谦谦君子,陌上其华

tags:

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

http://acm.hdu.edu.cn/showproblem.php?pid=1811

题意:

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"。

 

思路:
这道题目需要注意的就是存在“=”的情况,存在等号的话就相当于这两个是一个整体了,他们中间不可能再插进去分数不同的人了,所以可以用并查集并在一起,然后统一用root来代替这一整个整体即可。

然后就是普通的拓扑排序了。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,int> pll;
 15 const int INF = 0x3f3f3f3f;
 16 const int maxn = 10000 + 5;
 17 
 18 int n,m;
 19 int pre_n;
 20 int p[maxn];
 21 int vis[maxn];
 22 int degree[maxn];
 23 char c[2*maxn];
 24 int u[2*maxn],v[2*maxn];
 25 bool flag1,flag2;
 26 vector<int> G[maxn];
 27 
 28 int Find(int x)
 29 {
 30     return p[x]==x?x:p[x]=Find(p[x]);
 31 }
 32 
 33 void tuopu()
 34 {
 35     memset(vis,0,sizeof(vis));
 36     for(int i=1;i<=n;i++)
 37     {
 38         int pos=-1;
 39         int num=0;
 40         for(int j=0;j<pre_n;j++)
 41         {
 42             int u=Find(j);
 43             if(vis[u]!=i && degree[u]==0)
 44             {
 45                 vis[u]=i;
 46                 pos=u;
 47                 num++;
 48             }
 49         }
 50         if(num>1)  flag1=true;
 51         if(pos==-1)  {flag2=true;return;}
 52         degree[pos]=-1;
 53         for(int j=0;j<G[pos].size();j++)
 54         {
 55             int v=G[pos][j];
 56             degree[v]--;
 57         }
 58     }
 59     return;
 60 }
 61 
 62 int main()
 63 {
 64     //freopen("in.txt","r",stdin);
 65     while(~scanf("%d%d",&n,&m))
 66     {
 67         pre_n=n;
 68         for(int i=0;i<n;i++)  G[i].clear();
 69         memset(degree,0,sizeof(degree));
 70         for(int i=0;i<n;i++)  p[i]=i;
 71 
 72         for(int i=0;i<m;i++)
 73         {
 74             cin>>u[i]>>c[i]>>v[i];
 75             if(c[i]===)
 76             {
 77                 int x=Find(u[i]);
 78                 int y=Find(v[i]);
 79                 if(x!=y)
 80                 {
 81                     p[x]=y;
 82                     n--;
 83                 }
 84             }
 85         }
 86 
 87         for(int i=0;i<m;i++)
 88         {
 89             int x=Find(u[i]);
 90             int y=Find(v[i]);
 91             if(c[i]==>)
 92             {
 93                 G[x].push_back(y);
 94                 degree[y]++;
 95             }
 96             else if(c[i]==<)
 97             {
 98                 G[y].push_back(x);
 99                 degree[x]++;
100             }
101         }
102 
103         flag1=flag2=false;
104         tuopu();
105         if(flag2)  puts("CONFLICT");
106         else if(flag1)  puts("UNCERTAIN");
107         else puts("OK");
108     }
109     return 0;
110 }

 

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

HDU 1811 Rank of Tetris ??????????????? + ????????????

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

hdu 1811 Rank of Tetris 并查集+拓扑排序

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

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

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