hdu3926Hand in Hand

http://acm.hdu.edu.cn/showproblem.php?pid=3926

View Code
hdu3926Hand in Hand
/*题意:判断两幅图是否同构 图中即判断图中环和链的个数是否相同 环和链是否一一相对应
利用并查集 一个集合中若人数num[]和拉手对手p[]相等 则为环,num[]==p[]+1则为链
*/
#include
<iostream>
#include
<set>
#include
<algorithm>
using namespace std;
const int maxn=10001;
int pre[maxn],p[maxn],num[maxn];
int find(int x)
{
int r=x;
while(pre[r]!=r)r=pre[r];
int i=x,j;
while(i!=r)
{
j
=pre[i];
pre[i]
=r;
i
=j;
}
return r;
}
void join(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
pre[fx]
=fy;
num[fy]
+=num[fx];
num[fx]
=0;
p[fy]
+=p[fx]+1;
p[fx]
=0;
}
else
{
p[fx]
++;
}
}
int main()
{
int cas,Cas=0,a,b,n,m;
scanf(
"%d",&cas);
while(cas--)
{
set <int> cir,li;
cir.clear();
li.clear();
scanf(
"%d%d",&n,&m);
for(int i=1;i<=n;i++){p[i]=0,pre[i]=i;num[i]=1;}
for(int i=0;i<m;i++)
{
scanf(
"%d%d",&a,&b);
join(a,b);
}

for(int i=1;i<=n;i++)
{
if(pre[i]==i)
{
if(num[i]==p[i])cir.insert(num[i]);
else li.insert(num[i]);
}
}
int numcir=cir.size(),numli=li.size();
for(int i=1;i<=n;i++){p[i]=0;pre[i]=i;num[i]=1;}
scanf(
"%d%d",&n,&m);
for(int i=0;i<m;i++)
{
scanf(
"%d%d",&a,&b);
join(a,b);
}
for(int i=1;i<=n;i++)
{
if(pre[i]==i)
{
if(num[i]==p[i])cir.insert(num[i]);
else li.insert(num[i]);
}
}
cout
<<"Case #"<<++Cas<<": ";

if(numcir==cir.size()&&numli==li.size())cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
原文地址:https://www.cnblogs.com/sook/p/2156408.html