http://acm.hdu.edu.cn/showproblem.php?pid=3926
这道题是判断两个图是不是同构相似。只要判断图中环的个数和链的个数,和每个环的节点数和链的节点数是否相等。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 30000 5 using namespace std; 6 7 int t,n1,m1,n2,m2; 8 int f[maxn],num[maxn]; 9 int cicl[maxn]; 10 struct node 11 { 12 int lis; 13 int cicl; 14 bool operator <(const node &a)const 15 { 16 return ((lis<a.lis)||(lis==a.lis&&cicl<a.cicl)); 17 } 18 }p1[maxn],p2[maxn]; 19 20 int find1(int x) 21 { 22 if(x==f[x]) return x; 23 return f[x]=find1(f[x]); 24 } 25 26 void merge1(int a,int b) 27 { 28 int fa=find1(a); 29 int fb=find1(b); 30 if(fa==fb) 31 { 32 cicl[fa]=1; 33 return; 34 } 35 num[fa]+=num[fb]; 36 f[fb]=fa; 37 } 38 39 void inti(int n) 40 { 41 for(int i=0; i<=n; i++) 42 { 43 f[i]=i; 44 num[i]=1; 45 } 46 memset(cicl,0,sizeof(cicl)); 47 } 48 49 int main() 50 { 51 scanf("%d",&t); 52 for(int ca=1; ca<=t; ca++) 53 { 54 scanf("%d%d",&n1,&m1); 55 inti(n1); 56 for(int i=0; i<m1; i++) 57 { 58 int a,b; 59 scanf("%d%d",&a,&b); 60 merge1(a,b); 61 } 62 int cnt1=0; 63 for(int i=1; i<=n1; i++) 64 { 65 if(f[i]==i) 66 { 67 p1[cnt1].lis=num[i]; 68 p1[cnt1++].cicl=cicl[i]; 69 } 70 } 71 scanf("%d%d",&n2,&m2); 72 inti(n2); 73 int cnt2=0; 74 for(int i=0; i<m2; i++) 75 { 76 int a1,b1; 77 scanf("%d%d",&a1,&b1); 78 merge1(a1,b1); 79 } 80 for(int i=1; i<=n2; i++) 81 { 82 if(f[i]==i) 83 { 84 p2[cnt2].lis=num[i]; 85 p2[cnt2++].cicl=cicl[i]; 86 } 87 } 88 //printf("....%d %d\n",cnt1,cnt2); 89 printf("Case #%d: ",ca); 90 if(n1!=n2) 91 { 92 printf("NO\n"); 93 continue; 94 } 95 if(cnt1!=cnt2) 96 { 97 printf("NO\n"); 98 continue; 99 } 100 bool flag=true; 101 sort(p1,p1+cnt1); 102 sort(p2,p2+cnt2); 103 for(int i=0; i<cnt1; i++) 104 { 105 if(p1[i].lis!=p2[i].lis||(p1[i].cicl!=p2[i].cicl)) 106 { 107 flag=false; 108 printf("NO\n"); 109 break; 110 } 111 } 112 if(flag) 113 { 114 printf("YES\n"); 115 } 116 } 117 return 0; 118 }