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;
}

 

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