前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hand in Hand(并查集)

Hand in Hand(并查集)

作者头像
用户1624346
发布2018-04-17 15:47:41
5620
发布2018-04-17 15:47:41
举报
文章被收录于专栏:calmoundcalmound

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

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

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

代码语言:javascript
复制
#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++);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012-08-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档