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 }
时间: 2024-10-05 15:46:13