Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)F. Tree Factory

F. Tree Factory

time limit per test

2 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Bytelandian Tree Factory produces trees for all kinds of industrial applications. You have been tasked with optimizing the production of a certain type of tree for an especially large and important order.

The tree in question is a rooted tree with nn vertices labelled with distinct integers from 00 to n−1n−1. The vertex labelled 00 is the root of the tree, and for any non-root vertex vv the label of its parent p(v)p(v) is less than the label of vv.

All trees at the factory are made from bamboo blanks. A bamboo is a rooted tree such that each vertex has exactly one child, except for a single leaf vertex with no children. The vertices of a bamboo blank can be labelled arbitrarily before its processing is started.

To process a bamboo into another tree a single type of operation can be made: choose an arbitrary non-root vertex vv such that its parent p(v)p(v) is not a root either. The operation consists of changing the parent of vv to its parent's parent p(p(v))p(p(v)). Note that parents of all other vertices remain unchanged, in particular, the subtree of vv does not change.

Efficiency is crucial, hence you have to minimize the number of operations to make the desired tree from a bamboo blank. Construct any optimal sequence of operations to produce the desired tree.

Note that the labelling of the resulting tree has to coincide with the labelling of the desired tree. Formally, the labels of the roots have to be equal, and for non-root vertices with the same label the labels of their parents should be the same.

It is guaranteed that for any test present in this problem an answer exists, and further, an optimal sequence contains at most 106106 operations. Note that any hack that does not meet these conditions will be invalid.

Input

The first line contains a single integer nn — the number of vertices in the tree (2≤n≤1052≤n≤105).

The second line contains n−1n−1 integers p(1),…,p(n−1)p(1),…,p(n−1) — indices of parent vertices of 1,…,n−11,…,n−1 respectively (0≤p(i)<i0≤p(i)<i).

Output

In the first line, print nn distinct integers id1,…,idnid1,…,idn — the initial labelling of the bamboo blank starting from the root vertex (0≤idi<n0≤idi<n).

In the second line, print a single integer kk — the number of operations in your sequence (0≤k≤1060≤k≤106).

In the third line print kk integers v1,…,vkv1,…,vk describing operations in order. The ii-th operation consists of changing p(vi)p(vi) to p(p(vi))p(p(vi)). Each operation should be valid, i.e. neither vivi nor p(vi)p(vi) can be the root of the tree at the moment.

Examples

input

Copy

5
0 0 1 1

output

Copy

0 2 1 4 3
2
1 3

input

Copy

4
0 1 2

output

Copy

0 1 2 3
0

 

 

分析:容易想到从树变成一条链。因为要求操作最小,同时我们每次操作最多能将整棵树的深度+1,那么猜测最小操作数应该是n-dep。那么我们只需要保证每次操作都能使树的深度+1即可。找到最长链,然后在分叉处进行操作,那么这样就可以保证每次都能使深度+1。

#include <bits/stdc++.h>
using namespace std;
int fa[100004];
set<int>v[100004];
vector<int>op;
int maxi,point;
void dfs1(int u,int dep){
    if(dep > maxi){
        maxi = dep;
        point = u;
    }
    for (auto it : v[u]){
        dfs1(it,dep+1);
    }
}
void dfs2(int u){
    if(u == 0)return;
    if(v[fa[u]].size() == 1)dfs2(fa[u]);
    else {
        v[fa[u]].erase(u);
        int x = *v[fa[u]].begin();
        fa[u] = x;
        v[x].insert(u);
        op.push_back(u);
        dfs2(u);
    }
}
int main(){
    int n;
    cin>>n;
    fa[0] = -1;
    for (int i = 0; i < n-1; ++i) {
        int p;
        scanf("%d",&p);
        v[p].insert(i+1);
        fa[i+1]=p;
    }
    maxi = 1;
    point = 0;
    dfs1(0,1);
    dfs2(point);
    int u = 0;
    while(v[u].size()){
        printf("%d ",u);
        u = *v[u].begin();
    }
    printf("%d\n",u);
    printf("%d\n",n - maxi);
    for (int i = op.size() - 1; i >= 0; --i) {
        printf("%d ",op[i]);
    }
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值