刚开始的时候还没看懂题目,还以为看这两个图是不是一样呢。。。结果果断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;
}