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 }
posted @ 2014-07-21 20:41  Der_Z  阅读(170)  评论(0编辑  收藏  举报