hdu 3926 hands in hands

https://vjudge.net/problem/HDU-3926

题意:
有n个小朋友,他们之间手拉手,但是一只手只能拉一只手或者不拉,现在给出两个图,表示拉手关系,问这两个图是否同构。
思路:
一开始被同构难住了,后来思考发现,每一个联通分量只能是一条链或者一个简单的环,这样就比较好判断了。利用并查集统计每一个连通分量中的点,然后判断类型,判断类型的时候用度数是否为1来判断是否为链,然后将每一个连通分量先根据大小,再根据类型进行排序,最后把两个图进行一个比较即可。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 #include <vector>
  5 using namespace std;
  6 
  7 int fao[10004],fat[10004],d[10004];
  8 vector<int> g[10004],v[10004];
  9 
 10 struct node
 11 {
 12     int ty,sz;
 13 };
 14 
 15 node disc1[10004],disc2[10004];
 16 
 17 void init1(int n)
 18 {
 19     for (int i = 1;i <= n;i++)
 20     {
 21         fao[i] = i;
 22     }
 23 }
 24 
 25 void init2(int n)
 26 {
 27     for (int i = 1;i <= n;i++)
 28         fat[i] = i;
 29 }
 30 
 31 int fin1(int x)
 32 {
 33     if (x == fao[x]) return x;
 34     else return fao[x] = fin1(fao[x]);
 35 }
 36 
 37 int fin2(int x)
 38 {
 39     if (x == fat[x]) return x;
 40     else return fat[x] = fin2(fat[x]);
 41 }
 42 
 43 void unit1(int x,int y)
 44 {
 45     x = fin1(x);
 46     y = fin1(y);
 47 
 48     if (x != y) fao[x] = y;
 49 }
 50 
 51 void unit2(int x,int y)
 52 {
 53     x = fin2(x);
 54     y = fin2(y);
 55 
 56     if (x != y) fat[x] = y;
 57 }
 58 
 59 int dfs1(int n)
 60 {
 61     for (int i = 0;i < g[n].size();i++)
 62     {
 63         int t = g[n][i];
 64 
 65         if (d[t] == 1) return 0;
 66     }
 67 
 68     return 1;
 69 }
 70 
 71 int dfs2(int n)
 72 {
 73     for (int i = 0;i < v[n].size();i++)
 74     {
 75         int t = v[n][i];
 76 
 77         if (d[t] == 1) return 0;
 78     }
 79 
 80     return 1;
 81 }
 82 
 83 bool cmp(node aa,node bb)
 84 {
 85     if (aa.sz == bb.sz)
 86         return aa.ty < bb.ty;
 87     return aa.sz < bb.sz;
 88 }
 89 
 90 int main()
 91 {
 92     int t;
 93 
 94     scanf("%d",&t);
 95 
 96     int cas = 0;
 97 
 98     while(t--)
 99     {
100         memset(v,0,sizeof(v));
101         memset(g,0,sizeof(g));
102         memset(disc1,0,sizeof(disc1));
103         memset(disc2,0,sizeof(disc2));
104         memset(d,0,sizeof(d));
105 
106         int n,m;
107 
108         scanf("%d%d",&n,&m);
109 
110         init1(n);
111 
112         for (int i = 0;i < m;i++)
113         {
114             int x,y;
115 
116             scanf("%d%d",&x,&y);
117 
118             d[x]++;
119             d[y]++;
120 
121             unit1(x,y);
122         }
123 
124         for (int i = 1;i <= n;i++)
125         {
126             g[fin1(i)].push_back(i);
127         }
128 
129         int cnt1 = 0;
130 
131         for (int i = 1;i <= n;i++)
132         {
133             if (g[i].size() != 0)
134             {
135                 disc1[cnt1].sz = g[i].size();
136                 disc1[cnt1].ty = dfs1(i);
137                 cnt1++;
138             }
139         }
140 
141         scanf("%d%d",&n,&m);
142 
143         init2(n);
144 
145         int cnt2 = 0;
146 
147         memset(d,0,sizeof(d));
148 
149         for (int i = 0;i < m;i++)
150         {
151             int x,y;
152 
153             scanf("%d%d",&x,&y);
154 
155             d[x]++;d[y]++;
156 
157             unit2(x,y);
158         }
159 
160         for (int i = 1;i <= n;i++)
161             v[fin2(i)].push_back(i);
162 
163         for (int i = 1;i <= n;i++)
164         {
165             if (v[i].size() != 0)
166             {
167                 disc2[cnt2].sz = v[i].size();
168                 disc2[cnt2].ty = dfs2(i);
169                 cnt2++;
170             }
171         }
172 
173         sort(disc1,disc1 + cnt1,cmp);
174         sort(disc2,disc2 + cnt2,cmp);
175 
176         bool ff = 0;
177 
178         if (cnt1 != cnt2) ff = 1;
179 
180         for (int i = 0;i < cnt1;i++)
181         {
182             if (disc1[i].sz != disc2[i].sz) ff = 1;
183             if (disc1[i].ty != disc2[i].ty) ff = 1;
184         }
185 
186         if (ff) printf("Case #%d: NO\n",++cas);
187         else printf("Case #%d: YES\n",++cas);
188     }
189 
190     return 0;
191 }

 

posted @ 2017-07-10 17:57  qrfkickit  阅读(148)  评论(0编辑  收藏  举报