http://acm.hdu.edu.cn/showproblem.php?pid=3926

这道题是判断两个图是不是同构相似。只要判断图中环的个数和链的个数,和每个环的节点数和链的节点数是否相等。

hdu 3926 Hand in Hand_i++hdu 3926 Hand in Hand_编程_02
  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 }
View Code