關鍵是注意到,每個點的度至多為2,所以整個圖是由一些獨立的鏈和環構成的。然後統計某種鏈或是環的個數,如果同種鏈或環的數目相同,則是同構圖。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 10010struct 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;}