链接:http://acm.hdu.edu.cn/showproblem.php?pid=3926
题意:T组样例。每个样例给出两个图。每个图的所有点最大度数为2,问两个图是否同构。
思路:由于点的最大度为2,那么图可能会分为若干个连通块,并且要么是一个圆要么是一条线,显然用并查集记下每个练通块的大小以及是圆是线,排序后判断一下即可。
PS:以为是个图同构的题,没想到是道并查集水题。以后还是不用结构体封装了,作用不大。。。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e4+10;
int u,v;
struct node
{
int num;
bool yuan;
};
struct Union_Find
{
int fa[N],n,m,fu,fv;
struct node a[N];
void Init()
{
for(int i=1;i<=n;i++)
a[i].yuan=0,a[i].num=1,fa[i]=i;
return ;
}
int Getf(int x)
{
return fa[x]==x?x:fa[x]=Getf(fa[x]);
}
void Merge(int u,int v)
{
fu=Getf(u); fv=Getf(v);
if(fu!=fv)
{
fa[fu]=fv;
a[fv].num+=a[fu].num;
a[fu].num=0;
}
else
a[fv].yuan=1;
return ;
}
}g1,g2;
bool Cmp(const node& a,const node& b)
{
if(a.num==b.num)
return a.yuan>b.yuan;
else return a.num>b.num;
}
int main(void)
{
int t,tt=0;
bool no;
scanf("%d",&t);
while(t--)
{
no=0;
scanf("%d%d",&g1.n,&g1.m);
g1.Init();
for(int i=1;i<=g1.m;i++)
{
scanf("%d%d",&u,&v);
g1.Merge(u,v);
}
scanf("%d%d",&g2.n,&g2.m);
if(g2.n!=g1.n||g2.m!=g1.m)
{
no=1;
}
if(!no)
g2.Init();
for(int i=1;i<=g2.m;i++)
{
scanf("%d%d",&u,&v);
if(no) continue;
g2.Merge(u,v);
}
printf("Case #%d: ",++tt);
if(no)
{
printf("NO\n");
continue;
}
sort(g1.a+1,g1.a+g1.n+1,Cmp);
sort(g2.a+1,g2.a+g2.n+1,Cmp);
for(int i=1;i<=g1.n;i++)
{
if(g1.a[i].num!=g2.a[i].num||g1.a[i].yuan!=g2.a[i].yuan)
{
no=1;
break;
}
}
printf(no?"NO\n":"YES\n");
}
return 0;
}