hdu3926 Hand in Hand 判断同构

  因为每个人小朋友只有两只手,所以每个点最多只有2度。图有可能是环、链,以及环和链构成的复杂图。  

  如何判断两幅图是否相似呢?判断相似是判断两幅图的圈的数量,以及构成圈的点数是否相同。还有判断链的数目和构成链的点数是否相同。

  具体实现:标记环(或者链),按照点的数目排序。如果点数相同,环排在前面。然后逐个判断,如果全部都相同,就是同构。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10010;
struct node
{
    int cnt;
    bool iscc;
}arr1[N],arr2[N];
int f[N],r[N],iscir[N];
bool cmp(const node &x, const node &y)
{
    if(x.cnt!=y.cnt) return x.cnt<y.cnt;
    if(x.iscc<y.iscc) return 1;
    return 0;
}
int Find(int x)
{
    if(x==f[x]) return x;
    return f[x]=Find(f[x]);
}
void Link(int i,int j)
{
    int a=Find(i),b=Find(j);
    if(a!=b) {f[b]=a;r[a]+=r[b];}
    else iscir[a]=1;
}
void init()
{
    for(int i=0;i<N;i++)
    {
        f[i]=i;iscir[i]=0;r[i]=1;
    }
}
int main()
{
    //freopen("test.txt","r",stdin);
    int ca,k,i,j,x,y,n1,m2,n2,m1,a,b;
    k=1;
    scanf("%d",&ca);
    while(ca--)
    {
        scanf("%d%d",&n1,&m1);
        init();
        while(m1--)
        {
            scanf("%d%d",&x,&y);
            Link(x,y);
        }
        a=0;
        for(i=1;i<=n1;i++)
        {
            if(i==Find(i))
            {
                arr1[a].cnt=r[i];
                arr1[a++].iscc=iscir[i];
            }
        }
        scanf("%d%d",&n2,&m2);
        init();
        while(m2--)
        {
            scanf("%d%d",&x,&y);
            Link(x,y);
        }
        b=0;
        for(i=1;i<=n1;i++)
        {
            if(i==Find(i))
            {
                arr2[b].cnt=r[i];
                arr2[b++].iscc=iscir[i];
            }
        }
        printf("Case #%d: ",k++);
        if(n2!=n1||m2!=m1)
        {
            printf("NO
");
            continue;
        }
        if(a==b)
        {
            sort(arr1,arr1+a,cmp);
            sort(arr2,arr2+a,cmp);
            for(i=0;i<a;i++)
            {
                if(arr1[i].cnt!=arr2[i].cnt) break;
                if(arr1[i].iscc!=arr2[i].iscc) break;
            }
            if(i==a) printf("YES
");
            else printf("NO
");
        }
        else printf("NO
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Potato-lover/p/3930266.html