zoukankan      html  css  js  c++  java
  • HDU3926 Hand in Hand (并查集求同构)

    本题可以用并查集求同构的原因是,每个点只能和两个点相连,因此只有环和链两种情况,没有其他的种类。

    首先我们知道同构就是有相同个数长度的的链和相同个数长度的环。这样我们在并查集只需要维护两个信息。

    一个是集合大小,一个是有没有环。因为环只可能在头尾节点,所以只需要把环记录在我们并查集的根节点就行了。就能代表这个集合是不是环

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<string> 
    #include<set>
    #include<map>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int mod=1e9+7;
    int p[N];
    int d[N];
    int sign[N];
    int n,m;
    struct node{
        int cnt;
        int st;
        bool operator <(const node &t){
            if(cnt==t.cnt)
            return st<t.st;
            return cnt<t.cnt;
        }
    }s1[N],s2[N];
    void init(){
        int i;
        for(i=1;i<=n;i++){
            p[i]=i;
            d[i]=1;
            sign[i]=0;
        }
    }
    int find(int x){
        if(p[x]!=x){
            p[x]=find(p[x]);
        }
        return p[x];
    }
    int main(){
          int t;
          cin>>t;
          int q=1;
          while(t--){
            cin>>n>>m;
            int n1=n,m1=m;
            init();
            int i;
            for(i=1;i<=m;i++){
                int a,b;
                cin>>a>>b;
                int pa=find(a),pb=find(b);
                if(pa==pb){
                    sign[pa]=1;    
                }
                else{
                    p[pa]=pb;
                    d[pb]+=d[pa];
                }
            }
            int idx=0;
            for(i=1;i<=n;i++){
                if(p[i]==i){
                    s1[idx++]={d[i],sign[i]};
                }
            }
            sort(s1,s1+idx);
            cin>>n>>m;
            init();
            for(i=1;i<=m;i++){
                int a,b;
                cin>>a>>b;
                int pa=find(a),pb=find(b);
                if(pa==pb){
                    sign[pa]=1;    
                }
                else{
                    p[pa]=pb;
                    d[pb]+=d[pa];
                }
            }
            idx=0;
            for(i=1;i<=n;i++){
                if(p[i]==i){
                    s2[idx++]={d[i],sign[i]};
                }
            }
            sort(s2,s2+idx);
            int flag=0;
            for(i=0;i<idx;i++){
                if(s1[i].cnt!=s2[i].cnt||s1[i].st!=s2[i].st){
                    flag=1;
                    break;
                }
            }
            if(n1!=n||m1!=m){
                printf("Case #%d: NO
    ",q++);
                continue;
            }
            if(!flag)
            printf("Case #%d: YES
    ",q++);
            else
            printf("Case #%d: NO
    ",q++);
        }
    }
    View Code
  • 相关阅读:
    css
    js -【 数组】判断一个变量是数组类型的几种方法
    【消灭代办】第2周
    【本周面试题】第2周
    【本周面试题】第1周
    【消灭代办】第1周
    echarts
    css
    js
    JS方法
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12373202.html
Copyright © 2011-2022 走看看