HDU 3926 Hand in Hand (同构图)

来源:互联网 发布:win7杀毒软件 知乎 编辑:程序博客网 时间:2024/05/14 22:39

刚开始的时候还没看懂题目,还以为看这两个图是不是一样呢。。。结果果断WA。。
题意:给你两个图问你是不是同构的,两个图同构就是指两个的节点数要相同,然后图的结构也要相同。比如说有多少个环呀,每个环中有多少个节点呀,要相同。顺序没有要求
这个题,每个孩子有两只手,所以可能为连通分量,就是要么是环,要么是链,不可能两种情况共存,因为每个点的度数最多为二嘛。
然后我们判断两个图是不是同构的话,我们要用并查集来判断两通块是不是环,和统计连通块的节点数
最后排个序,比较一下就好了

#include<time.h>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const int maxn = 1e4+5;int f[maxn];//要用 一个统一的规则struct node{    int cnt;//num    int type;};node G1[maxn],G2[maxn];void init(){    for(int i=0;i<maxn;i++){        f[i]=i;        G1[i].cnt=1;G1[i].type=0;        G2[i].cnt=1;G2[i].type=0;    }}bool cmp(node a,node b){    if(a.cnt!=b.cnt) return a.cnt>b.cnt;    else return a.type>b.type;}int findf(int k){    if(k!=f[k]) return f[k]=findf(f[k]);    return k;}int main(){    int T;    scanf("%d",&T);    int case1=0;    while(T--)    {        int n1,m1;        init();        scanf("%d %d",&n1,&m1);        for(int i=0;i<m1;i++)        {            int a,b;            scanf("%d %d",&a,&b);            int root1=findf(a);            int root2=findf(b);            if(root1==root2)                G1[root1].type=1;            else {                if(G1[root1].cnt>=G1[root2].cnt){                G1[root1].cnt+=G1[root2].cnt;                f[root2]=root1;                }                else                {                    G1[root2].cnt+=G1[root1].cnt;                    f[root1]=root2;                }            }        }        for(int i=0;i<maxn;i++)            f[i]=i;        int n2,m2;        scanf("%d %d",&n2,&m2);        for(int i=0;i<m2;i++)        {            int a,b;            scanf("%d %d",&a,&b);            int root1=findf(a);            int root2=findf(b);            if(root1==root2)            {                G2[root1].type=1;            }            else {                if(G2[root1].cnt>=G2[root2].cnt){                G2[root1].cnt+=G2[root2].cnt;                f[root2]=root1;                }                else{                    G2[root2].cnt+=G2[root1].cnt;                    f[root1]=root2;                }            }        }        printf("Case #%d: ",++case1);        if((n2!=n1)||(m1!=m2))            printf("NO\n");        else {            sort(G1+1,G1+n1+1,cmp);//这里是n呀兄弟            sort(G2+1,G2+n2+1,cmp);            int flag=0;            for(int i=1;i<=n1;i++)            {                if(G1[i].cnt!=G2[i].cnt||G1[i].type!=G2[i].type)                {                    flag=1;                    break;                }            }            if(flag) printf("NO\n");            else printf("YES\n");        }    }    return  0;}
原创粉丝点击