给以一条链,每次可以把一个点变成它父亲的父亲儿子,问最少多少次可以变成给定的树?
考虑将一颗树变成一条链,那么就是把一个点变成兄弟的儿子。
而考虑最少需要多少步,每一次操作最多让树高加一,那么最少需要n-max(dep)-1次。
那么为了让操作次数达到最少,每次都必须更新最长链。
#include <bits/stdc++.h>
using namespace std;
#define N 500005
#define M 2010
#define ll long long
#define mod 1000000007
#define go(i,a,b) for(int i=(a);i<=(b);i++)
#define dep(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define inf 0x3f3f3f3f
#define ld long double
#define pii pair<int,int>
#define fi first
#define se second
#define vi vector<int>
#define add(a,b) (a+=(b)%mod)%=mod
#define lowb(c,len,x) lower_bound(c+1,c+len+1,x)-c
#define uppb(c,len,x) upper_bound(c+1,c+len+1,x)-c
#define ls i*2+1
#define rs i*2+2
#define mid (l+r)/2
#define root 1,n,0
#define lson l,mid,ls
#define rson mid+1,r,rs
#define l(x) (x&-x)
#define ms(a,b) memset(a,b,sizeof a)
#define muti int T;cin>>T;while(T--)
int dep[N],ans[N],nxt[N],r,n,u;
vi g[N];
bool cmp(int a,int b){return dep[a]>dep[b]; }
void dfs(int u){
for(int to:g[u]){
dfs(to);
dep[u]=max(dep[u],dep[to]+1);
}
}
void dfs1(int u){
if(!g[u].size())return ;
sort(g[u].begin(),g[u].end(),cmp);
go(i,1,g[u].size()-1){
ans[++r]=g[u][i-1];
g[g[u][i]].pb(g[u][i-1]);
}
dfs1(nxt[u]=g[u][g[u].size()-1]);
}
int main()
{
cin>>n;
go(i,1,n-1)scanf("%d",&u),g[u].pb(i);
dfs(0);
dfs1(0);
putchar('0');
for(int i=nxt[0];i;i=nxt[i])printf(" %d",i);cout<<endl;
cout<<r<<endl;
dep(i,r,1)printf("%d%c",ans[i],i==1?'\n':' ');
return 0;
}