(3926)HDU

#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>




#define ll __int64
#define lll unsigned long long
#define MAX 1000009
#define MAXN 10009
#define eps 1e-8
#define INF 0xfffffff


using namespace std;


/*
题意:给你两个图,问你两个图是否相似,因为一个人就有两个手,所以度为2,所以只有链或者环。所以我们只要看每个节点下的环数和链的长度就可以了
所以我们就要有排序。
*/
int pre1[MAX];
int pre2[MAX];
int num1;
int num2;


struct node
{
    int son;//儿子节点
    int ring;//成环
} p1[MAXN],p2[MAXN];


void init()//初始化
{
    for(int i = 0; i<MAXN; i++)
    {
        p1[i].son = 1;
        p1[i].ring = 0;
        pre1[i] = i;


        p2[i].son = 1;
        p2[i].ring = 0;
        pre2[i] = i;
    }


}


int Find(int x,int pre[])//查找函数,压缩路径
{
    if(pre[x]!=x)
    {
        pre[x] = Find(pre[x],pre);
    }
    return pre[x];
}


void Union(int x,int y,int pre[],node z[])
{
    int xx =Find(x,pre);
    int yy =Find(y,pre);
    if(xx==yy)//如果父亲节点相同则成环
    {
        z[xx].ring = 1;
    }
    else
    {
        if(z[xx].son>=z[yy].son)//把儿子少的附着给儿子多的
        {
            pre[yy] = xx;
            z[xx].son+=z[yy].son;
        }
        else
        {
            pre[xx] = yy;
            z[yy].son+=z[xx].son;
        }
    }
}
bool cmp(node x,node y)//先儿子后环数排序
{
    if(x.son!=y.son)
        return x.son < y.son;
    else
        return x.ring < y.ring;
}
int ok(int num,node x[],node y[])
{
    sort(x+1,x+num+1,cmp);
    sort(y+1,y+num+1,cmp);
    for(int i = 1; i<=num; i++)//检查每个节点
    {
        if(x[i].son!=y[i].son||(x[i].son==y[i].son&&x[i].ring!=y[i].ring))
            return 0;
    }
    return 1;
}
int main()
{
    int t;
    int link1,link2;
    int num1,num2;
    int x,y;
    int flag;
    int d = 1;
    scanf("%d",&t);
    while(t--)
    {
        flag = 0;
        init();
        scanf("%d%d",&num1,&link1);
        for(int i = 0; i<link1; i++)
        {
            scanf("%d%d",&x,&y);
            Union(x,y,pre1,p1);
        }
        scanf("%d%d",&num2,&link2);
        for(int i = 0; i<link2; i++)
        {
            scanf("%d%d",&x,&y);
            Union(x,y,pre2,p2);
        }
        if(link2!=link1)//如果边数不同可以不用看了
        {
            printf("Case #%d: ",d++);
            puts("NO");
            continue;
        }
        flag = ok(num2,p1,p2);
        // cout<<"TEST: "<<flag<<endl;
        if(!flag)
        {
            printf("Case #%d: ",d++);
            puts("NO");
        }
        else
        {
            printf("Case #%d: ",d++);
            puts("YES");
        }
    }
    return 0;
}

你可能感兴趣的:((3926)HDU)