JZOJ 5454. 【NOIP2017提高A组冲刺11.5】仔细的检查

来源:互联网 发布:bitcomet mac版 编辑:程序博客网 时间:2024/06/05 10:17

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

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;}
阅读全文
1 0