您的位置:首页 > 其它

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

2015-12-10 16:20 204 查看


Rank of Tetris

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 7410    Accepted Submission(s): 2115


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:  1272 1198 1829 1558 1325 

 

Statistic | Submit | Discuss | Note

这个题正解应该是把相等的点,并查集缩为一点,然后对所有处理后的点,进行拓扑排序,(以下的点都是缩点后的)

CONFLICT   判断方法  :  拓扑排序可以判断是否有环,OK要求无环。

信息不足可以归结为     :必须从多个点出发才能遍历完所有点。

我的处理是从某个入度为0的点dfs,看能否找到一条路径通过所有点。(若没有,证明信息不足)

如果以上两个条件都足,证明OK。

其实正解的处理应该是充分利用拓扑排序的性质,在排序的时候,如果队列里有超过1个结点,证明此时此刻必须从不止一点出发,才能遍历完所有点,换言之,信息不足。

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<cctype>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI (4.0*atan(1.0))
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   ind<<1,le,mid
#define rson    ind<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk    make_pair
#define _f     first
#define _s     second
using namespace std;
//const int INF=    ;
typedef long long ll;
//const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
const int INF =0x3f3f3f3f;
const int maxn=10000+20    ;
const int maxm= 20000+20   ;

int n,m;
bool fin;
vector<int> G[maxn];
bool vis[maxn];
int pre[maxn];
int deg[maxn];
vector<int > ve;
set<int >se;
struct Q
{
int x,y;
char op;
Q(){}
Q(int x,int y,char op):x(x),y(y),op(op){}

} q[maxm];

void init()
{
FOR0(i,n) pre[i]=i,G[i].clear(),deg[i]=0;
}

int find(int x)
{
return pre[x]==x?x:pre[x]=find(pre[x]);
}
void merge(int s,int t)
{
int x=find(s);

int y=find(t);
if(x==y)  return;
pre[x]=y;

}

inline void add_edge(int s,int t)
{
G[s].push_back(t);
deg[t]++;
}

bool topsort()
{
ve.clear();
queue<int >q;
int cnt=0;
for(set<int >::iterator it=se.begin();it!=se.end();it++)
{
int x=*it;
if(deg[x]==0)  {q.push(x);ve.push_back(x);}

}

while(!q.empty())
{
int x=q.front();q.pop();
cnt++;
for(int i=0;i<G[x].size();i++)
{
int y=G[x][i];
if(--deg[y]==0) q.push(y);
}

}
if(cnt<se.size())  return false;
return true;

}

void dfs(int x,int cnt)
{
if(cnt==se.size())  {fin=1;return;}
if(fin)  return;
for(int i=0;i<G[x].size()&& !fin;i++)
{
int y=G[x][i];
if(vis[y])  continue;
vis[y]=1;

dfs(y,cnt+1);
vis[y]=0;
}
}

int main()
{
int x,y;char op;
while(~scanf("%d%d",&n,&m))
{
init();
int cnt=0;
bool ok=1;
for(int i=1;i<=m;i++)
{
scanf("%d %c %d",&x,&op,&y);

if(op!= '=')    q[++cnt]=Q(x,y,op);

else   merge(x,y);

}

se.clear();

for(int i=0;i<n;i++)  se.insert(find(i));

for(int i=1;i<=cnt&&ok;i++)
{
int x=find(q[i].x);
int y=find(q[i].y);
if(x==y)  ok=0;
if(q[i].op=='>')  add_edge(x,y);
else         add_edge(y,x);

}
if(!ok || !topsort()) {puts("CONFLICT");continue;}

if(ve.size()>1 )  {puts("UNCERTAIN");continue;}
memset(vis,0,sizeof vis);
int x=ve[0];
vis[x]=1;
fin=0;
dfs(x,1);
if(!fin)    puts("UNCERTAIN");
else  puts("OK");

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: