hdu 3926 特殊同构图+并查集

关键是注意到,每个点的度至多为2,所以整个图是由一些独立的链和环构成的。然后统计某种链或是环的个数,如果同种链或环的数目相同,则是同构图。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define maxn 10010
struct bcj {
        int fa,num;
        bool cir;
        void init(){fa=cir=0,num=1;}
    };
struct Bcj {
    bcj no[maxn];
    void init(int n=maxn){
        for(int i=1;i<=n;++i)
            no[i].init();
    }
    int find(int p) {
        return no[p].fa?no[p].fa=find(no[p].fa):p;
    }
    void uni(int p,int q) {
        int i=find(p),j=find(q);
        if(i!=j)
            no[i].num<no[j].num?no[i].fa=j,no[j].num+=no[i].num:no[j].fa=i,no[i].num+=no[j].num;
        else no[i].cir=true;
    }
}bc1,bc2;

void solve(int &n,int &m,Bcj &bc) {
    cin >> n >> m;
    bc.init(n);
    for(int i=1;i<=m;++i) {
        int a,b;
        cin >> a >> b;
        bc.uni(a,b);
    }
}

bool cmp(const bcj &a,const bcj &b) {
    if(a.fa!=b.fa) return a.fa < b.fa;
    if(a.cir!=b.cir) return a.cir < b.cir;
    return a.num < b.num;
}

int main() {
    ios::sync_with_stdio(false);
    int T,cas=0;
    cin >> T;
    while(++cas<=T) {
        cout << "Case #" << cas << ": ";
        int n,m,n1,m1;
        solve(n,m,bc1);
        solve(n1,m1,bc2);
        if(n!=n1||m!=m1) {
            cout << "NO" << endl;
            continue;
        }
        sort(bc1.no+1,bc1.no+1+n,cmp);
        sort(bc2.no+1,bc2.no+1+n,cmp);
        bool flag=true;
        for(int i=1;i<=n&&(!bc1.no[i].fa||!bc1.no[i].fa);++i)
            if((bc1.no[i].fa!=bc2.no[i].fa)
               ||bc1.no[i].cir!=bc2.no[i].cir
               ||bc1.no[i].num!=bc2.no[i].num) {
                flag=false;break;
            }
        if(flag) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值