zoukankan      html  css  js  c++  java
  • HDU 3926 图的同构

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926

    题意:给定2个顶点度最大为2的无向图。问你这2个无向图是否同构。

    思路:

    1.最大度为2.说明这个图可能有多个连通分量,每个连通分量要么是环,要么是链。
    2.然后遍历每个连通分量,记录该连通分量的结点个数,以及该连通分量是环还是链。
    3.将第一个图按照结点个数排序(若子结点个数相同,则对链先排序)
    4.将第二个图按照步骤三排序
    5.比较排序后,2个图是否每个元素都相等。若相等,则相似。

    关于求链通分量,当然是并查集的一些基本操作了,不过合并的时候应该遵循孩子节点少的合并到孩子节点多的集合中(不然wa),然后就是排序后比较一下就可以了(因为图可能存在环,因此可以先按孩子节点的个数排,然后再按是否存在环排)

    #include<time.h>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN=10000+5;
    int na,ma,nb,mb,t,Ca=1,FaA[MAXN],FaB[MAXN];
    struct Node{
        int cnt; //连通分量的点数
        int Type; //1:是环  0:链
        Node(int a=1,int b=0):cnt(a),Type(b){};
    }GroupA[MAXN],GroupB[MAXN]; //图1,图2
    void Init(){ //初始化
        for(int i=0;i<MAXN;i++){
            FaA[i]=i; FaB[i]=i;    
            GroupA[i].cnt=1; GroupA[i].Type=0;
            GroupB[i].cnt=1; GroupB[i].Type=0;
        }
    }
    int Find(int x,int *Fa){ //并查集
        return x==Fa[x]?x:Fa[x]=Find(Fa[x],Fa);
    }
    void Union(int x,int y,int *Fa,Node *Group){//并查集
        int rootx=Find(x,Fa);
        int rooty=Find(y,Fa);
        if(rootx==rooty){ //存在环
            Group[rootx].Type=1;
        }
        else{ //把小的合并到大的树上
            if(Group[rootx].cnt>=Group[rooty].cnt){
                Group[rootx].cnt+=Group[rooty].cnt;
                Fa[rooty]=rootx;
            }
            else{
                Group[rooty].cnt+=Group[rootx].cnt;
                Fa[rootx]=rooty;
            }
        }
    }
    bool cmp(Node a,Node b){ //排序函数,先按点数排,点数相同则优先排链再到环
        if(a.cnt!=b.cnt){
            return a.cnt<b.cnt;
        }
        return a.Type<b.Type;
    }
    bool solve(){ //比较2个图是否同构
        sort(GroupA,GroupA+na+1,cmp);
        sort(GroupB,GroupB+nb+1,cmp);
        for(int i=0;i<=na;i++){
            if((GroupA[i].Type!=GroupB[i].Type)||(GroupA[i].cnt!=GroupB[i].cnt)){
                return false;
            }
        }
        return true;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--){
            Init();
            scanf("%d %d",&na,&ma);
            for(int i=1;i<=ma;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                Union(u,v,FaA,GroupA);
            }
            scanf("%d %d",&nb,&mb);
            for(int i=1;i<=mb;i++){
                int u,v;
                scanf("%d %d",&u,&v);
                Union(u,v,FaB,GroupB);
            }
            printf("Case #%d: ",Ca++);
            if((na!=nb)||(ma!=mb)){ //点数/边数不匹配
                printf("NO
    ");
                continue;
            }
            if(solve()){
                printf("YES
    ");
            }
            else{
                printf("NO
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Sort
    RAID
    LeetCode总结 -- 一维动态规划篇
    Count and Say
    Dynamic Programming Introduction
    Mongodb与Redis应用指标对比
    精通有状态vs无状态(Stateful vs Stateless)—Immutable模式之姐妹篇
    Windows 安装 pytorch3d
    GitHub 图片无法显示 或 gist 无法访问
    LaTeX符号表,数学公式速查必备
  • 原文地址:https://www.cnblogs.com/kirito520/p/5659214.html
Copyright © 2011-2022 走看看