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 */