Hand in Hand(并查集)

题意:判断两个图形是否相似,根据题意可以知道图形的分量,不是环就是链,所以我们只要依次两个图形是否一样就可以了

分析:若两个图形完全一样的话,那么它们成环和成链的个数必定一样,当然成环(链)的点的个数也是一样的,所以我们可以忽视结点的本身,

         而值注重这个点代表的意义就可以。一样的两图排序后,自然会有对等的点和对等相同意义的点

#include<stdio.h>
#include<algorithm>
using namespace std;

const int MAXN=10010;
int n1,n2,m1,m2;
int father1[MAXN],father2[MAXN];

struct Graph
{
    int son;
    bool ring;
}gra1[MAXN],gra2[MAXN];

void Make_set(int n,int father[],Graph gra[])
{
    for(int i=1;i<MAXN;i++)
    {
        father[i]=i;
        gra[i].son=1;
        gra[i].ring=false;//初始化为链
    }
}

int Find(int x,int father[])
{
    int r=x;
    while(r!=father[r])
    {
        r=father[r];
    }
    if(r!=x) father[x]=r;
    return r;
}

void Union(int x,int y,Graph gra[],int father[])//这里直接用x,y避免错误
{
    x=Find(x,father);
    y=Find(y,father);
    if(x==y)//这里注意必须注意是父节点,避免错误把a,b都省略
    {
        gra[x].ring=true;
        return ;
    }
    else
    {
        if(gra[x].son>=gra[y].son)
        {
             gra[x].son+=gra[y].son;
             father[y]=x;
        }
        else
        {
            gra[y].son+=gra[x].son;
            father[x]=y;
        }
    }
}

bool cmp(Graph a,Graph b)
{
    if(a.son<b.son) return true;
    else if(a.son==b.son && a.ring<b.ring) return true;//这里只写<是错的,没有=的话存在>的情况
    return false;
}

bool _Judge(Graph g1[],Graph g2[],int num)
{
    sort(g1+1,g1+n1+1,cmp);
    sort(g2+1,g2+n2+1,cmp);
    for(int i=1;i<=num;i++)
    {
        //printf("%d %d %d %d\n",g1[i].son,g2[i].son,g1[i].ring,g2[i].ring);
        if(g1[i].son!=g2[i].son || (g1[i].son==g2[i].son && g1[i].ring!=g2[i].ring)) return false;
    }
    return true;
}

int main()
{
    int T,i,a,b;
    int cas=1;
    int flag;
    scanf("%d",&T);
    while(T--)
    {
        flag=true;
        scanf("%d%d",&n1,&m1);
        Make_set(n1,father1,gra1);
        for(i=0;i<m1;i++)
        {
            scanf("%d%d",&a,&b);
            Union(a,b,gra1,father1);
        }
        scanf("%d%d",&n2,&m2);
        Make_set(n2,father2,gra2);
        if(n1!=n2) flag=false;
        for(i=0;i<m2;i++)
        {
            scanf("%d%d",&a,&b);
            if(flag==false) continue;
            Union(a,b,gra2,father2);
        }
        flag=_Judge(gra1,gra2,n1);
        if(flag==false) printf("Case #%d: NO\n",cas++);
        else printf("Case #%d: YES\n",cas++);
    }
}
posted @ 2012-08-11 16:40  calmound  阅读(234)  评论(0编辑  收藏  举报