hdu 1811 Rank of Tetris
题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1811
这题的关键点就是对 “=” 的处理,这个要用到并查集。把是“=”关系的点放在统一集合内,处理其中每一个点时都当做处理根结点。
数据不全的情况是同时出现两个点的入度为0,(当两个点具有“ = ”关系时,我们默认是一个点)。
源代码:
1 #include<iostream> 2 #include<vector> 3 #include<queue> 4 #include<stdio.h> 5 #include<cstring> 6 #define maxn 100010 7 using namespace std; 8 int a[maxn],b[maxn],from[maxn],pa[maxn],sum,n,m; 9 queue<int>q; 10 char c[maxn]; 11 vector<int>map[maxn]; 12 bool uncertain; 13 int find(int a){ 14 if(pa[a] == a)return a; 15 return pa[a] = find(pa[a]); 16 } 17 18 int link(int a,int b){ 19 a = find(a); 20 b = find(b); //没写这个就re了…… 21 if(a==b)return 0; 22 pa[b]=a; 23 return 1; 24 25 } 26 27 void topo(){ 28 29 for(int i=0;i<n;i++) 30 if(from[i]==0&&find(i)==i){ 31 q.push(i); 32 } 33 while(!q.empty()){ 34 if(q.size()>1) uncertain=true; 35 int temp=q.front(); 36 q.pop(); 37 sum--; 38 for(int i=0;i<map[temp].size();i++) 39 { 40 if(--from[map[temp][i]]==0){ 41 q.push(map[temp][i]); 42 } 43 } 44 } 45 46 } 47 int main(){ 48 while(scanf("%d %d",&n,&m)!=EOF){ 49 uncertain=false; 50 sum=n; 51 memset(from,0,sizeof(from)); 52 for(int i=0;i<n;i++){ 53 pa[i]=i; 54 map[i].clear(); 55 } 56 57 for(int i=0;i<m;i++){ 58 scanf("%d %c %d",&a[i],&c[i],&b[i]); 59 if(c[i]=='=') { //对“=”预处理 60 if(link(a[i],b[i])) 61 sum--; 62 } 63 } 64 for(int i=0;i<m;i++){ 65 int x=find(a[i]); 66 int y=find(b[i]); 67 if(c[i]=='=') continue; 68 if(c[i]=='>') { 69 map[x].push_back(y); 70 from[y]++; 71 72 } 73 if(c[i]=='<'){ 74 map[y].push_back(x); 75 from[x]++; 76 77 } 78 } 79 topo(); 80 if(sum>0)printf("CONFLICT\n"); 81 else if(uncertain) printf("UNCERTAIN\n"); 82 else printf("OK\n"); 83 } 84 }