杭电1811 Rank of Tetris(拓扑排序+并查集缩点)

来源:互联网 发布:手机游戏充值端口代理 编辑:程序博客网 时间:2024/06/01 18:28

Rank of Tetris

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


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 30 > 11 < 20 > 24 41 = 21 > 32 > 00 > 13 31 > 01 > 22 < 1
 

Sample Output
OKCONFLICTUNCERTAIN
 

Author
linle
 

Source
HDOJ 2007 Summer Exercise(2) 
/*好痛苦啊,,尼玛,合并函数写错竟然测试数据还能过。。。。。。。。。我去。。。。一直RE,爆栈,把并查集改成非递归了,结果超时。。。。。。。加油!!!Time:2014-12-3 8:33*/#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>using namespace std;const int MAXN=10050;const int MAXM=20050;int father[MAXN],in[MAXN];int X[MAXM],Y[MAXM];char cmd[MAXM];vector<int>G[MAXN];int num,n,m;int find(int x){return father[x]==x?x:father[x]=find(father[x]);}/*int find(int x){int root=x;while(root!=father[root]){root=father[root];}while(x!=root){int temp=father[x];father[x]=root;x=temp;}return x;}*/void Init(){num=n;for(int i=0;i<n;i++){father[i]=i;G[i].clear();in[i]=0;}}bool merge(int x,int y){int a=find(x);int b=find(y);if(a==b) return false;father[b]=a;return true;}void topSort(){queue<int>q;while(!q.empty())q.pop(); for(int i=0;i<n;i++){if(in[i]==0&&find(i)==i)q.push(i);}bool flag=false;while(!q.empty()){if(q.size()>1) {flag=true;}int t=q.front(); q.pop();num--; for(int i=0;i<G[t].size();i++){if(--in[G[t][i]]==0) q.push(G[t][i]);}}if(num>0)//如果没有入度为0 ,肯定冲突 puts("CONFLICT");else if(flag)puts("UNCERTAIN");elseputs("OK");}int main(){while(scanf("%d%d",&n,&m)!=EOF){Init();for(int i=0;i<m;i++){scanf("%d %c %d",&X[i],&cmd[i],&Y[i]);if(cmd[i]=='='){if(merge(X[i],Y[i]))//缩点 num--;}}for(int i=0;i<m;i++){if(cmd[i]!='='){int a=find(X[i]);int b=find(Y[i]);if(cmd[i]=='>'){G[a].push_back(b);in[b]++;}else{G[b].push_back(a);in[a]++;}}}topSort();}return 0;}
/*额。。。做过的还是不会做。。Time:2014-12-12 23:30 更新*/#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<queue>using namespace std;const int MAX=10000+10;int father[MAX],in[MAX];int n,m,num;vector<vector<int> >G(MAX);int find(int x){return father[x]==x?x:father[x]=find(father[x]);}void Init(){for(int i=0;i<=n;i++){if(G[i].size())G[i].clear();father[i]=i;in[i]=0;}}void topSort(){queue<int>q;for(int i=0;i<n;i++){if(in[i]==0&&find(i)==i){//用根节点,额,这儿变了下就行了。。。。 q.push(i);in[i]--; }}int flag=0;//printf("%d\n",q.size()); while(!q.empty()){if(q.size()>1){flag=1;}num--; int cur=find(q.front());q.pop();//printf("cur=%d\n",G[cur].size());for(int i=0;i<G[cur].size();i++){int temp=find(G[cur][i]);//注意拓扑的时候用集合的根节点拓扑。。调试好长时间 if(--in[temp]==0){q.push(temp);}}}if(num>0)//这儿有个优先级问题。。。有环优先 puts("CONFLICT");else if(flag){puts("UNCERTAIN");}else if(num==0)puts("OK");}int main(){char cmd[MAX];int x[MAX],y[MAX];int a,b;while(scanf("%d%d",&n,&m)!=EOF){Init();num=n;for(int i=0;i<m;i++){scanf("%d %c %d",&x[i],&cmd[i],&y[i]);if(cmd[i]=='='){a=find(x[i]); b=find(y[i]);if(a!=b){father[a]=b;num--;}}}for(int i=0;i<m;i++){a=find(x[i]);b=find(y[i]);// cmd[i]!="=" if(cmd[i]=='>'){//printf("a=%d b=%d\n",a,b);G[a].push_back(b);in[b]++;}else if(cmd[i]=='<'){G[b].push_back(a);in[a]++;}}topSort();}return 0;}


0 0
原创粉丝点击