Tree Factory cf596div1D

给以一条链,每次可以把一个点变成它父亲的父亲儿子,问最少多少次可以变成给定的树?

考虑将一颗树变成一条链,那么就是把一个点变成兄弟的儿子。

而考虑最少需要多少步,每一次操作最多让树高加一,那么最少需要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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章