HDU 3926 Hand in Hand
http://acm.hdu.edu.cn/showproblem.php?pid=3926
题意:一群小孩随机跑动,一声令下就要牵手……就是给你两个图,每个点度数为2,判断两个图是否相等。(每个图只能是链、环)。
题解:使用并查集判断,点数是否在一个集合内,是否成环。然后依据每棵树的节点数数量进行排序,进行判断。之前并查集模板好像有错。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cmath> 6 #include <string> 7 #include <vector> 8 #include <list> 9 #include <map> 10 #include <queue> 11 #include <stack> 12 #include <bitset> 13 #include <algorithm> 14 #include <numeric> 15 #include <functional> 16 #include <set> 17 #include <fstream> 18 19 using namespace std; 20 21 const int maxn=10010; 22 23 int par[maxn]; 24 int rankh[maxn]; 25 int ISCIRCLE[maxn]; 26 int pos1,pos2; 27 struct node{ 28 int rankn,iscircle; 29 }; 30 node n1[maxn],n2[maxn]; 31 32 bool cmp(const node& n1,const node& n2) 33 { 34 if(n1.rankn!=n2.rankn) return n1.rankn<n2.rankn; 35 if(n1.iscircle<n2.iscircle) return true; 36 return false; 37 } 38 39 void init(int n) 40 { 41 memset(ISCIRCLE,0,sizeof(ISCIRCLE)); 42 for(int i=0;i<=n;i++) 43 { 44 par[i]=i; 45 rankh[i]=1; 46 } 47 } 48 49 int find(int x) 50 { 51 if(par[x]==x) 52 { 53 return x; 54 } 55 else{ 56 return par[x]=find(par[x]); 57 } 58 } 59 60 void unite(int x,int y) 61 { 62 x=find(x); 63 y=find(y); 64 if(x==y) 65 { 66 ISCIRCLE[x]=1; 67 return; 68 } 69 if(rankh[x]<rankh[y]) 70 { 71 par[x]=y; 72 rankh[y]+=rankh[x]; 73 } 74 else{ 75 par[y]=x; 76 rankh[x]+=rankh[y]; 77 //if(rankh[x]==rankh[y]) rankh[x]++; 78 } 79 } 80 81 bool judge() 82 { 83 if(pos1!=pos2) return false; 84 sort(n1,n1+pos1,cmp); 85 sort(n2,n2+pos2,cmp); 86 for(int i=0;i<pos1;i++) 87 { 88 if(n1[i].rankn!=n2[i].rankn) return false; 89 if(n1[i].iscircle!=n2[i].iscircle) return false; 90 } 91 return true; 92 } 93 94 int main() 95 { 96 //freopen("/Users/apple/Desktop/暑假/14(1)/14(1)/in","r",stdin); 97 int T; 98 scanf("%d",&T); 99 int ca=1; 100 while(T--) 101 { 102 printf("Case #%d: ",ca++); 103 int N1,M1; 104 scanf("%d%d",&N1,&M1); 105 int u,v; 106 init(N1); 107 for(int i=0;i<M1;i++) 108 { 109 scanf("%d%d",&u,&v); 110 unite(u,v); 111 } 112 pos1=0; 113 for(int i=1;i<=N1;i++) 114 { 115 if(i==find(i)) 116 { 117 n1[pos1].rankn=rankh[i]; 118 n1[pos1].iscircle=ISCIRCLE[i]; 119 pos1++; 120 } 121 } 122 int N2,M2; 123 scanf("%d%d",&N2,&M2); 124 init(N2); 125 for(int i=0;i<M2;i++) 126 { 127 scanf("%d%d",&u,&v); 128 unite(u,v); 129 } 130 if(N1!=N2||M1!=M2) 131 { 132 puts("NO"); 133 continue; 134 } 135 pos2=0; 136 for(int i=1;i<=N2;i++) 137 { 138 if(i==find(i)) 139 { 140 n2[pos2].rankn=rankh[i]; 141 n2[pos2].iscircle=ISCIRCLE[i]; 142 pos2++; 143 } 144 } 145 if(judge()) puts("YES"); 146 else puts("NO"); 147 } 148 return 0; 149 }