hdu 3926 同构图(并查集)

题意:给出两图,判断是否是同构图。

题解:判断给出的链和环,若果是链,则判断链里边时候是同构,排序。如果是环,则判断环里边的个数。

要判断每个点,把每条边加入到并查集中去,记录是环或者链。每次并查集加入的时候,链或者环的长度会变化,所以要改变链的长度。

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <iostream>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
using namespace std;
#define ll long long
const int maxn=50010;
struct node
{
    int num;
    int cl;
    bool operator < (const node &tmp) const
    {
        if(tmp.num==num) return tmp.cl<cl;
        return tmp.num<num;
    }
}nd1[maxn],nd2[maxn];
int f[maxn];
int found(int x)
{
    if(x!=f[x]) f[x]=found(f[x]);
    return f[x];
}
int  main()
{
   // freopen("C:\Users\Administrator\Desktop\a.txt","r",stdin);
    //ios::sync_with_stdio(false);
    //freopen("C:\Users\Administrator\Desktop\b.txt","w",stdout);
    int n1,n2,m1,m2,T,Case=0;
    scanf("%d",&T);
    while(T--)
    {
        bool flag=true;
        scanf("%d%d",&n1,&m1);
        for(int i=0;i<=maxn;i++)
        {
             nd1[i].num=1,nd1[i].cl=0;
             nd2[i].num=1,nd2[i].cl=0;
        }
        for(int i=0;i<=n1;i++) f[i]=i;
        for(int i=0;i<m1;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            int fx=found(a),fy=found(b);
            if(fx!=fy)
            {
                f[fx]=fy;
                nd1[fy].num+=nd1[fx].num;
                nd1[fx].num=0;
            }
            else nd1[fy].cl=1;
        }
        scanf("%d%d",&n2,&m2);
        if(n1!=n2||m1!=m2) flag=false;
        for(int i=0;i<=n2;i++) f[i]=i;
        for(int i=0;i<m2;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            int fx=found(a),fy=found(b);
            if(fx!=fy)
            {
                f[fx]=fy;
                nd2[fy].num+=nd2[fx].num; //改变链的长度,合并完后也要改变
                nd2[fx].num=0;
            }
            else nd2[fy].cl=1;
        }
        sort(nd1+1,nd1+n1+1);
        sort(nd2+1,nd2+n2+1);
        for(int i=1;i<=n1;i++)
        {
            if(nd1[i].num!=nd2[i].num||nd1[i].cl!=nd2[i].cl)
            {
                flag=false;
                break;
            }
        }
        if(!flag) printf("Case #%d: NO
",++Case);
        else printf("Case #%d: YES
",++Case);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7653058.html