您的位置:首页 > 其它

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

2017-07-19 11:47 363 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1811

题意:

[align=left]Problem Description[/align]
自从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来代替这一整个整体即可。

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

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = 10000 + 5;

int n,m;
int pre_n;
int p[maxn];
int vis[maxn];
int degree[maxn];
char c[2*maxn];
int u[2*maxn],v[2*maxn];
bool flag1,flag2;
vector<int> G[maxn];

int Find(int x)
{
return p[x]==x?x:p[x]=Find(p[x]);
}

void tuopu()
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
int pos=-1;
int num=0;
for(int j=0;j<pre_n;j++)
{
int u=Find(j);
if(vis[u]!=i && degree[u]==0)
{
vis[u]=i;
pos=u;
num++;
}
}
if(num>1)  flag1=true;
if(pos==-1)  {flag2=true;return;}
degree[pos]=-1;
for(int j=0;j<G[pos].size();j++)
{
int v=G[pos][j];
degree[v]--;
}
}
return;
}

int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
pre_n=n;
for(int i=0;i<n;i++)  G[i].clear();
memset(degree,0,sizeof(degree));
for(int i=0;i<n;i++)  p[i]=i;

for(int i=0;i<m;i++)
{
cin>>u[i]>>c[i]>>v[i];
if(c[i]=='=')
{
int x=Find(u[i]);
int y=Find(v[i]);
if(x!=y)
{
p[x]=y;
n--;
}
}
}

for(int i=0;i<m;i++)
{
int x=Find(u[i]);
int y=Find(v[i]);
if(c[i]=='>')
{
G[x].push_back(y);
degree[y]++;
}
else if(c[i]=='<')
{
G[y].push_back(x);
degree[x]++;
}
}

flag1=flag2=false;
tuopu();
if(flag2)  puts("CONFLICT");
else if(flag1)  puts("UNCERTAIN");
else puts("OK");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: