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

题意:中文题意,就不多解释。
思路:这题比普通的拓扑排序多了一个相等的关系,而且当拓扑排序的结果不唯一的时候是输出”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");
    }
}

你可能感兴趣的:(hdu1811 Rank of Tetris(并查集+拓扑排序))