#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define ll __int64
#define lll unsigned long long
#define MAX 1000009
#define MAXN 10009
#define eps 1e-8
#define INF 0xfffffff
using namespace std;
/*
题意:给你两个图,问你两个图是否相似,因为一个人就有两个手,所以度为2,所以只有链或者环。所以我们只要看每个节点下的环数和链的长度就可以了
所以我们就要有排序。
*/
int pre1[MAX];
int pre2[MAX];
int num1;
int num2;
struct node
{
int son;//儿子节点
int ring;//成环
} p1[MAXN],p2[MAXN];
void init()//初始化
{
for(int i = 0; i<MAXN; i++)
{
p1[i].son = 1;
p1[i].ring = 0;
pre1[i] = i;
p2[i].son = 1;
p2[i].ring = 0;
pre2[i] = i;
}
}
int Find(int x,int pre[])//查找函数,压缩路径
{
if(pre[x]!=x)
{
pre[x] = Find(pre[x],pre);
}
return pre[x];
}
void Union(int x,int y,int pre[],node z[])
{
int xx =Find(x,pre);
int yy =Find(y,pre);
if(xx==yy)//如果父亲节点相同则成环
{
z[xx].ring = 1;
}
else
{
if(z[xx].son>=z[yy].son)//把儿子少的附着给儿子多的
{
pre[yy] = xx;
z[xx].son+=z[yy].son;
}
else
{
pre[xx] = yy;
z[yy].son+=z[xx].son;
}
}
}
bool cmp(node x,node y)//先儿子后环数排序
{
if(x.son!=y.son)
return x.son < y.son;
else
return x.ring < y.ring;
}
int ok(int num,node x[],node y[])
{
sort(x+1,x+num+1,cmp);
sort(y+1,y+num+1,cmp);
for(int i = 1; i<=num; i++)//检查每个节点
{
if(x[i].son!=y[i].son||(x[i].son==y[i].son&&x[i].ring!=y[i].ring))
return 0;
}
return 1;
}
int main()
{
int t;
int link1,link2;
int num1,num2;
int x,y;
int flag;
int d = 1;
scanf("%d",&t);
while(t--)
{
flag = 0;
init();
scanf("%d%d",&num1,&link1);
for(int i = 0; i<link1; i++)
{
scanf("%d%d",&x,&y);
Union(x,y,pre1,p1);
}
scanf("%d%d",&num2,&link2);
for(int i = 0; i<link2; i++)
{
scanf("%d%d",&x,&y);
Union(x,y,pre2,p2);
}
if(link2!=link1)//如果边数不同可以不用看了
{
printf("Case #%d: ",d++);
puts("NO");
continue;
}
flag = ok(num2,p1,p2);
// cout<<"TEST: "<<flag<<endl;
if(!flag)
{
printf("Case #%d: ",d++);
puts("NO");
}
else
{
printf("Case #%d: ",d++);
puts("YES");
}
}
return 0;
}
#include<cstdio>
#include<string.h>
#include<string>
#include<stack>
#include<set>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define ll __int64
#define lll unsigned long long
#define MAX 1000009
#define MAXN 10009
#define eps 1e-8
#define INF 0xfffffff
using namespace std;
/*
题意:给你两个图,问你两个图是否相似,因为一个人就有两个手,所以度为2,所以只有链或者环。所以我们只要看每个节点下的环数和链的长度就可以了
所以我们就要有排序。
*/
int pre1[MAX];
int pre2[MAX];
int num1;
int num2;
struct node
{
int son;//儿子节点
int ring;//成环
} p1[MAXN],p2[MAXN];
void init()//初始化
{
for(int i = 0; i<MAXN; i++)
{
p1[i].son = 1;
p1[i].ring = 0;
pre1[i] = i;
p2[i].son = 1;
p2[i].ring = 0;
pre2[i] = i;
}
}
int Find(int x,int pre[])//查找函数,压缩路径
{
if(pre[x]!=x)
{
pre[x] = Find(pre[x],pre);
}
return pre[x];
}
void Union(int x,int y,int pre[],node z[])
{
int xx =Find(x,pre);
int yy =Find(y,pre);
if(xx==yy)//如果父亲节点相同则成环
{
z[xx].ring = 1;
}
else
{
if(z[xx].son>=z[yy].son)//把儿子少的附着给儿子多的
{
pre[yy] = xx;
z[xx].son+=z[yy].son;
}
else
{
pre[xx] = yy;
z[yy].son+=z[xx].son;
}
}
}
bool cmp(node x,node y)//先儿子后环数排序
{
if(x.son!=y.son)
return x.son < y.son;
else
return x.ring < y.ring;
}
int ok(int num,node x[],node y[])
{
sort(x+1,x+num+1,cmp);
sort(y+1,y+num+1,cmp);
for(int i = 1; i<=num; i++)//检查每个节点
{
if(x[i].son!=y[i].son||(x[i].son==y[i].son&&x[i].ring!=y[i].ring))
return 0;
}
return 1;
}
int main()
{
int t;
int link1,link2;
int num1,num2;
int x,y;
int flag;
int d = 1;
scanf("%d",&t);
while(t--)
{
flag = 0;
init();
scanf("%d%d",&num1,&link1);
for(int i = 0; i<link1; i++)
{
scanf("%d%d",&x,&y);
Union(x,y,pre1,p1);
}
scanf("%d%d",&num2,&link2);
for(int i = 0; i<link2; i++)
{
scanf("%d%d",&x,&y);
Union(x,y,pre2,p2);
}
if(link2!=link1)//如果边数不同可以不用看了
{
printf("Case #%d: ",d++);
puts("NO");
continue;
}
flag = ok(num2,p1,p2);
// cout<<"TEST: "<<flag<<endl;
if(!flag)
{
printf("Case #%d: ",d++);
puts("NO");
}
else
{
printf("Case #%d: ",d++);
puts("YES");
}
}
return 0;
}
355

被折叠的 条评论
为什么被折叠?



