hdu 3926 Hand in Hand

来源:互联网 发布:win8网络图标无法启用 编辑:程序博客网 时间:2024/04/29 03:30

Hand in Hand

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 122768/62768 K (Java/Others)
Total Submission(s): 871    Accepted Submission(s): 330


Problem Description
In order to get rid of Conan, Kaitou KID disguises himself as a teacher in the kindergarten. He knows kids love games and works out a new game called "hand in hand". 

Initially kids run on the playground randomly. When Kid says "stop", kids catch others' hands immediately. One hand can catch any other hand randomly. It's weird to have more than two hands get together so one hand grabs at most one other hand. After kids stop moving they form a graph.

Everybody takes a look at the graph and repeat the above steps again to form another graph. Now Kid has a question for his kids: "Are the two graph isomorphism?" 
 

Input
The first line contains a single positive integer T( T <= 100 ), indicating the number of datasets.
There are two graphs in each case, for each graph:
first line contains N( 1 <= N <= 10^4 ) and M indicating the number of kids and connections.
the next M lines each have two integers u and v indicating kid u and v are "hand in hand".
You can assume each kid only has two hands.
 

Output
For each test case: output the case number as shown and "YES" if the two graph are isomorphism or "NO" otherwise.
 

Sample Input
23 21 22 33 23 22 13 31 22 33 13 11 2
 

Sample Output
Case #1: YESCase #2: NO
题意:每个人手拉手,每个点的度最多为2,构成图中环或链,判断两个这样的图是否同构。
思路:用并查集合并,得到若干个集合,比较两个图中集合是否相同,包括集合的个数,集合中点的个数,集合中点的构成是链还是环。
AC代码:
#include <iostream>#include <cstring>#include <string>#include <cstdio>#include <algorithm>#include <queue>#include <map>#include <cmath>#include <vector>#include <cstdlib>using namespace std;const int MAX=10005;int fa1[MAX],fa2[MAX];struct graph{    int son;         //集合中点的个数    bool is_ring;   //是否为环的标志}g1[MAX],g2[MAX]; bool cmp(graph a,graph b)     //先按集合点的个数排序,若相等,再按是否为环排序{    if(a.son!=b.son)    return a.son<b.son;    return a.is_ring<b.is_ring;}int Find_set(int n,int fa[]){    if(n!=fa[n])    fa[n]=Find_set(fa[n],fa);    return fa[n];}void Union(int a,int b,int fa[],graph g[]){    int ra=Find_set(a,fa);    int rb=Find_set(b,fa);    if(ra==rb) g[ra].is_ring=true;      //有环    else    {        if(g[ra].son>=g[rb].son)        {            fa[rb]=ra;            g[ra].son+=g[rb].son;        }        else        {            fa[ra]=rb;            g[rb].son+=g[ra].son;        }    }}void init(){    for(int i=0; i<MAX; i++)    {        fa1[i]=i;        g1[i].son=1;        g1[i].is_ring=false;        fa2[i]=i;        g2[i].son=1;        g2[i].is_ring=false;    }}bool Compare(int num){    sort(g1+1,g1+num+1,cmp);    sort(g2+1,g2+num+1,cmp);    for(int i=1;i<=num;i++)    //若两个集合点的个数不相等,或个数相等但不同时为链或环    if(g1[i].son!=g2[i].son||(g1[i].son==g2[i].son&&g1[i].is_ring!=g2[i].is_ring))     return false;    return true;}int main(){    int t,c=0,num,edg1,edg2,a,b;    scanf("%d",&t);    while(t--)    {        bool flag=true;        scanf("%d%d",&num,&edg1);        init();        for(int i=0;i<edg1;i++)        {            scanf("%d%d",&a,&b);            Union(a,b,fa1,g1);        }        scanf("%d%d",&num,&edg2);        if(edg2!=edg1)        flag=false;        for(int i=0;i<edg2;i++)        {            scanf("%d%d",&a,&b);            if(flag)            Union(a,b,fa2,g2);        }        if(!flag)        {            printf("Case #%d: NO\n",++c);            continue;        }        flag=Compare(num);        if(flag)        printf("Case #%d: YES\n",++c);        else        printf("Case #%d: NO\n",++c);    }    return 0;}