Description
nodgd家里种了一棵树,有一天nodgd比较无聊,就把这棵树画在了一张纸上。另一天nodgd更无聊,就又画了一张。
这时nodgd发现,两次画的顺序是不一样的,这就导致了原本的某一个节点u0在第一幅图中编号为u1,在第二副图中编号为u2。
于是,nodgd决定检查一下他画出的两棵树到底是不是一样的。nodgd已经给每棵树的节点都从1到n进行了编号,即每棵树有n个节点。
如果存在一个1到n的排列p1p2…pn,对于第一幅图中的任意一条边(u,v),在第二幅图中都能找到一条边(pu,pv),则认为这两幅图中的树是一样的。
Input
第一行一个整数n,表示节点的总数。
接下来n−1行,每行两个整数,表示第一幅图中的每一条边。
接下来n−1行,每行两个整数,表示第二幅图中的每一条边。
Output
如果两幅图的树是一样的,第一行输出”YES”,接下来1行输出一个1到n的排列p1p2…pn,两个数之间用空格间隔。当多个排列都满足题意时,你可以随便输出一个。
如果两幅图的树是不一样的,只输出一行”NO”。
注意输出的时候不要加引号。
Sample Input
输入1:
3
1 2
2 3
1 3
3 2
输入2:
4
1 2
2 3
3 4
1 2
1 3
1 4
Sample Output
输出1:
YES
1 3 2
输出2:
NO
Data Constraint
Solution
这题就直接找到树的重心,一层一层递归下去找就好了。
但是要注意每个重心都要比较一遍,因为不一定是对称的!
时间复杂度 O(N) 。
Code
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e5+1;
int n,tot,mx,mx1,pos,pos1;
int first[N],next[N<<1],en[N<<1];
int first1[N],next1[N<<1],en1[N<<1];
int f[N],g[N],size[N],size1[N],id[N],bz[N];
bool strange;
inline int read()
{
int X=0,w=1; char ch=0;
while(ch<'0' || ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();
return X*w;
}
inline void write(int x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void insert(int x,int y)
{
next[++tot]=first[x];
first[x]=tot;
en[tot]=y;
}
inline void insert1(int x,int y)
{
next1[++tot]=first1[x];
first1[x]=tot;
en1[tot]=y;
}
inline void dfs(int x,int y)
{
size[x]=1;
for(int i=first[x];i;i=next[i])
if(en[i]!=y)
{
dfs(en[i],x);
size[x]+=size[en[i]];
if(size[en[i]]>f[x]) f[x]=size[en[i]];
}
if(n-size[x]>f[x]) f[x]=n-size[x];
if(f[x]<mx) mx=f[pos=x];
}
inline void dfs1(int x,int y)
{
size1[x]=1;
for(int i=first1[x];i;i=next1[i])
if(en1[i]!=y)
{
dfs1(en1[i],x);
size1[x]+=size1[en1[i]];
if(size1[en1[i]]>g[x]) g[x]=size1[en1[i]];
}
if(n-size1[x]>g[x]) g[x]=n-size1[x];
if(!strange && g[x]<mx1) mx1=g[pos1=x];
}
inline bool judge(int x,int y,int x1,int y1)
{
if(size[x]!=size1[x1] || f[x]!=g[x1]) return false;
for(int i=first[x];i;i=next[i])
if(en[i]!=y)
{
bool pd=false;
for(int j=first1[x1];j;j=next1[j])
if(en1[j]!=y1 && bz[en1[j]]!=x && judge(en[i],x,en1[j],x1))
{
bz[en1[j]]=x;
id[en[i]]=en1[j];
pd=true;
break;
}
if(!pd) return false;
}
return true;
}
int main()
{
n=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
insert(x,y);
insert(y,x);
}
tot=0;
for(int i=1;i<n;i++)
{
int x=read(),y=read();
insert1(x,y);
insert1(y,x);
}
mx=mx1=1e9;
dfs(1,0),dfs1(1,0);
memset(f,0,sizeof(f));
dfs(pos,mx=0);
for(int i=1;i<=n;i++)
if(g[i]==mx1)
{
strange=true;
memset(g,0,sizeof(g));
memset(bz,0,sizeof(bz));
dfs1(i,0);
if(judge(pos,0,i,0))
{
id[pos]=i;
puts("YES");
for(int i=1;i<=n;i++) write(id[i]),putchar(' ');
return 0;
}
}
puts("NO");
return 0;
}