hdu 3926 Hand in Hand(同构图)

来源:互联网 发布:c语言for循环执行顺序 编辑:程序博客网 时间:2024/06/11 08:45

/*  判断2个图是否为同构图   只需要判断 图中存在的环跟链的个数是否相同, 环中链中元素个数是否相同

运用并查集可以做

*/

#include<cstdio>

#include<cstring>
#include<algorithm>
#include<cstdlib>
#define maxn 10001
using namespace std;


struct R
{
    int num,flag;
} r1[maxn],r2[maxn];
int p1[maxn],p2[maxn];
int cmp(const void *a,const void *b)
{
    struct R *p = (struct R*)a;
    struct R *q = (struct R*)b;
    if(p->num==q->num) return p->flag-q->flag;
    return p->num-q->num;
}


int find(int x,int *p)
{
    return p[x]==x?x:p[x]=find(p[x],p);
}
int Union(int x,int y,int *p,R *r)
{
    int px = find(x,p);
    int py = find(y,p);
    if(px==py)
        r[px].flag=1;
    else
    {
        if(r[px].num>=r[py].num)
        {
            p[py] = px;
            r[px].num += r[py].num;
        }
        else
        {
            p[px] = py;
            r[py].num += r[px].num;
        }
    }
}
int judge_same(int n1)
{
    qsort(r1,n1+1,sizeof(r1[0]),cmp);
    qsort(r2,n1+1,sizeof(r2[0]),cmp);
    for(int i = 1; i <= n1; i++)
    {
        if(r1[i].num!=r2[i].num||(r1[i].num==r2[i].num&&r1[i].flag!=r2[i].flag))
            return 0;
    }
    return 1;
}
int main()
{
    int t,u,v,count=1,n1,m1,n2,m2;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1; i<maxn; i++)
        {
            p1[i]=p2[i]=i;
            r1[i].num = r2[i].num=1;
            r1[i].flag = r2[i].flag=0;
        }
        scanf("%d%d",&n1,&m1);
        for(int i = 0; i < m1; i++)
        {
            scanf("%d%d",&u,&v);
            Union(u,v,p1,r1);
        }
        scanf("%d%d",&n2,&m2);
        int ok;
        for(int i = 0; i < m2; i++)
        {
            scanf("%d%d",&u,&v);
            Union(u,v,p2,r2);
        }
        ok = judge_same(n2);
        if(ok)
            printf("Case #%d: YES\n",count++);
        else
            printf("Case #%d: NO\n",count++);
    }
    return 0;
}
原创粉丝点击