• 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++);
        }
    }
  • 相关阅读:
    反向迭代
    c++知识点
    LeetCode-Count Bits
    LeetCode-Perfect Rectangle
    LeetCode-Perfect Squares
    LeetCode-Lexicographical Numbers
    LeetCode-Find Median from Data Stream
    LeetCode-Maximal Square
    LeetCode-Number of Digit One
    LeetCode-Combination Sum IV
  • 原文地址:https://www.cnblogs.com/zsboy/p/2633777.html
Copyright © 2020-2023  润新知