关键是注意到,每个点的度至多为2,所以整个图是由一些独立的链和环构成的。然后统计某种链或是环的个数,如果同种链或环的数目相同,则是同构图。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 10010
struct bcj {
int fa,num;
bool cir;
void init(){fa=cir=0,num=1;}
};
struct Bcj {
bcj no[maxn];
void init(int n=maxn){
for(int i=1;i<=n;++i)
no[i].init();
}
int find(int p) {
return no[p].fa?no[p].fa=find(no[p].fa):p;
}
void uni(int p,int q) {
int i=find(p),j=find(q);
if(i!=j)
no[i].num<no[j].num?no[i].fa=j,no[j].num+=no[i].num:no[j].fa=i,no[i].num+=no[j].num;
else no[i].cir=true;
}
}bc1,bc2;
void solve(int &n,int &m,Bcj &bc) {
cin >> n >> m;
bc.init(n);
for(int i=1;i<=m;++i) {
int a,b;
cin >> a >> b;
bc.uni(a,b);
}
}
bool cmp(const bcj &a,const bcj &b) {
if(a.fa!=b.fa) return a.fa < b.fa;
if(a.cir!=b.cir) return a.cir < b.cir;
return a.num < b.num;
}
int main() {
ios::sync_with_stdio(false);
int T,cas=0;
cin >> T;
while(++cas<=T) {
cout << "Case #" << cas << ": ";
int n,m,n1,m1;
solve(n,m,bc1);
solve(n1,m1,bc2);
if(n!=n1||m!=m1) {
cout << "NO" << endl;
continue;
}
sort(bc1.no+1,bc1.no+1+n,cmp);
sort(bc2.no+1,bc2.no+1+n,cmp);
bool flag=true;
for(int i=1;i<=n&&(!bc1.no[i].fa||!bc1.no[i].fa);++i)
if((bc1.no[i].fa!=bc2.no[i].fa)
||bc1.no[i].cir!=bc2.no[i].cir
||bc1.no[i].num!=bc2.no[i].num) {
flag=false;break;
}
if(flag) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}