hdu1811 Rank of Tetris【拓扑排序+并查集缩点】

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<queue>
  5 using namespace std;
  6 
  7 const int MAXN = 10005;
  8 
  9 int tree[MAXN],indegree[MAXN],n,m;
 10 int first[MAXN],sn[2*MAXN],en[2*MAXN],next[2*MAXN];
 11 struct edge
 12 {
 13     int s,e,type;
 14 }data[2*MAXN];
 15 
 16 bool cmp(const edge&a,const edge&b)
 17 {
 18     return a.type<b.type;
 19 }
 20 
 21 int find(int x)
 22 {
 23     if( -1==tree[x] )   return x;
 24     return tree[x]=find(tree[x]);
 25 }
 26 
 27 void merge(int x,int y)
 28 {
 29     x=find(x);
 30     y=find(y);
 31     if( x==y )  return;
 32     tree[y]=x;
 33 }
 34 
 35 void addEdge(int u,int v,int e)
 36 {
 37     u=find(u);
 38     v=find(v);
 39     indegree[v]++;
 40     sn[e]=u;
 41     en[e]=v;
 42     next[e]=first[u];
 43     first[u]=e;
 44 }
 45 
 46 int topoSort(void)
 47 {
 48     queue<int> Q;
 49     bool flag;
 50     int cnt,num=0;
 51 
 52     for(int i=0;i<n;i++)
 53         if( -1==tree[i] && !indegree[i] )  Q.push(i);
 54     cnt=Q.size();
 55     flag=cnt>1;
 56     while( !Q.empty() )
 57     {
 58         int cur=Q.front(),inc=0;
 59 
 60         Q.pop();
 61         for(int e=first[cur];e!=-1;e=next[e])
 62         {
 63             indegree[en[e]]--;
 64             if( !indegree[en[e]] )  {Q.push(en[e]);inc++;}
 65         }
 66         cnt+=inc;
 67         if( inc>1 ) flag=true;
 68     }
 69     for(int i=0;i<n;i++)    num+=tree[i]==-1;
 70     if( cnt==num )    return flag?1:0;
 71     return 2;
 72 }
 73 
 74 int main()
 75 {
 76     int u,v;
 77     char ch[5];
 78 
 79     while( ~scanf("%d%d",&n,&m) )
 80     {
 81         memset(tree,-1,n*sizeof(tree[0]));
 82         memset(first,-1,n*sizeof(first[0]));
 83         memset(indegree,0,n*sizeof(indegree[0]));
 84         for(int i=0;i<m;i++)
 85         {
 86             scanf("%d%s%d",&data[i].s,ch,&data[i].e);
 87             if( ch[0]=='=' )    data[i].type=0;
 88             else if( ch[0]=='<' )   data[i].type=1;
 89             else data[i].type=2;
 90         }
 91         sort(data,data+m,cmp);
 92         for(int i=0;i<m;i++)
 93             if( data[i].type==0 )   merge(data[i].s,data[i].e);
 94             else if( data[i].type==1 )  addEdge(data[i].e,data[i].s,i);
 95             else addEdge(data[i].s,data[i].e,i);
 96         int ans=topoSort();
 97         if( !ans )  puts("OK");
 98         else if( 1==ans )   puts("UNCERTAIN");
 99         else puts("CONFLICT");
100     }
101     return 0;
102 }
103 /*
104     没有“=”,拓扑排序即可解决。
105     对于相等的点,用并查集缩成一个点。
106     然后拓扑排序即可。
107     思路的来源,是因为在刷并查集专题,所以联想到并查集。
108     但自己想不到好的解释,来说明并查集这样处理为什么可行?
109     游客有好的想法的话,希望能说明下自己的想法。
110 */

 

posted @ 2012-12-08 16:33  kiwi_bird  阅读(192)  评论(0编辑  收藏  举报