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

来源:互联网 发布:如何开发聊天软件 编辑:程序博客网 时间:2024/05/21 10:34

题意:中文题意,就不多解释。
思路:这题比普通的拓扑排序多了一个相等的关系,而且当拓扑排序的结果不唯一的时候是输出”UNCERTAIN”.
然后这题处理相等的关系,由于是可以传递特性,果断选择并查集,将相等绑定在一起。然后把相等看成一个整体,对这些整体一块块拓扑排序。
当队列里出现两个以上入度为0的块,就说明解不唯一。
当最后还剩下没有排序的块,就说明排序矛盾。
没有出现以上情况就是ok

#include<bits/stdc++.h>using namespace std;int v[10000+10],f[10000+10],n,m;void init() {for(int i=0;i<=10005;i++) f[i]=i;}int Find(int x) {return x==f[x] ? x : f[x]=Find(f[x]);}bool Merge(int x,int y) {x=Find(x);y=Find(y);if(x!=y) { f[x]=y;return true;} else return false;}vector<int>G[10000+10];int main(){    while(~scanf("%d%d",&n,&m)){      init();      int sum=n;      memset(v,0,sizeof(v));      int A[10000+10],B[10000+10];char op[20000+10];      for(int i=0;i<m;i++){         scanf("%d %c %d",&A[i],&op[i],&B[i]);         if(op[i]=='=') if(Merge(A[i],B[i])) sum--;      }      for(int i=0;i<=n;i++) G[i].clear();      for(int i=0;i<m;i++){         if(op[i]=='=') continue;         int a=Find(A[i]);         int b=Find(B[i]);         if(op[i]=='>') G[a].push_back(b),v[b]++;         else if(op[i]=='<') G[b].push_back(a),v[a]++;      }      int flag=0;      queue<int>q;      for(int i=0;i<n;i++){         if(v[i]==0&&Find(i)==i) {q.push(i);}      }      while(!q.empty()){         sum--;         if(q.size()>1) flag=1;         int x=q.front();q.pop();         for(int i=0;i<G[x].size();i++){            v[G[x][i]]--;            if(v[G[x][i]]==0) q.push(G[x][i]);         }      }      if(sum>0) printf("CONFLICT\n");      else if(flag==1) printf("UNCERTAIN\n");      else printf("OK\n");    }}
0 0
原创粉丝点击