topic
https://gmoj.net/senior/#main/show/6838
answer
This question seemed strange, so I ignored it during the competition.
Consider that a point is split several times in the final graph, and it is found that the number of splits is equal to the number of times it passes -1. Taking the starting point as the root, the path taken is to walk around a lot of sub-trees and return, and then choose a son to go down and not come back. The same goes for this son.
How can we make as many points as possible that do not return (obviously when a point returns to its father, its father must split once)? This is equivalent to choosing the longest simple path on the tree, the diameter .
Therefore, this question only needs to find the diameter, take one of its end points as the root, and then for each point on the diameter, first walk its non-diameter son's subtree and return, and then go along the diameter Go down.
CODE
#include<cstdio>
using namespace std;
#define M 205
#define N 105
int f[N][2],son[N][2],fir[N],to[M],nex[M],p[100005],now[N],pre[N],len,node,s;
bool b[N];
inline void inc(int x,int y)
{
to[++s]=y,nex[s]=fir[x],fir[x]=s;
to[++s]=x,nex[s]=fir[y],fir[y]=s;
}
void getd(int k,int fa)
{
for(int i=fir[k];i;i=nex[i]) if(to[i]!=fa)
{
getd(to[i],k);
if(f[to[i]][0]+1>f[k][0])
f[k][1]=f[k][0],son[k][1]=son[k][0],
f[k][0]=f[to[i]][0]+1,son[k][0]=to[i];
else if(f[to[i]][0]+1>f[k][1])
f[k][1]=f[to[i]][0]+1,son[k][1]=to[i];
}
if(f[k][0]+f[k][1]>len) len=f[k][0]+f[k][1],node=k;
}
void dfs(int k,int fa)
{
p[++p[0]]=k;
for(int i=fir[k];i;i=nex[i]) if(to[i]!=fa&&to[i]!=pre[k])
dfs(to[i],k),p[++p[0]]=k;
if(pre[k]) dfs(pre[k],k);
}
int main()
{
freopen("combo.in","r",stdin);
freopen("combo.out","w",stdout);
int root,n,x,y,cnt;
scanf("%d",&n),cnt=n;
for(int i=1;i<n;++i) scanf("%d%d",&x,&y),inc(x,y);
getd(1,0),root=node,b[root]=1;
while(son[root][0]) pre[son[root][0]]=root,root=son[root][0],b[root]=1;
if(son[node][1])
{
pre[node]=x=son[node][1],b[x]=1;
while(son[x][0]) x=pre[x]=son[x][0],b[x]=1;
}
dfs(root,0);
printf("%d\n",p[0]-n);
for(int i=1;i<=p[0];++i)
{
if(!now[p[i]]) now[p[i]]=p[i];
else printf("%d ",now[p[i]]),p[i]=now[p[i]]=++cnt;
}
puts("");
for(int i=1;i<=p[0];++i) printf("%d ",p[i]);
puts("");
return 0;
}