题目描述
猴猴最喜欢在树上玩耍,一天猴猴又跳上了一棵树,这棵树有N个苹果,每个苹果有一个编号,分别为0~N-1,它们之间由N-1个树枝相连,猴猴可以从树枝的一端爬到树枝的另一端,所以猴猴可以从任意一个苹果的位置出发爬到任意猴猴想去的苹果的位置。猴猴开始在编号为K的苹果的位置,并且把这个苹果吃了,之后每一天猴猴都要去吃一个苹果,但是树上那么多苹果吃哪个呢?猴猴想到自己去吃苹果时一定会把路上遇到的苹果都吃掉,于是猴猴决定去吃能让自己这天吃的苹果数量最多的那个苹果,如果有多个苹果满足条件,猴猴就会去吃这些中编号最小的苹果,那么猴猴会按照什么顺序吃苹果呢?
输入
第一行两个数N和K。(N<=50000)
第2-N行,第i+1行的数字Ai表示i和Ai之间有一根树枝相连。
输出
每行一个数字,依次表示猴猴所在的位置
样例输入 Copy
7 2
0
1
2
2
1
4
样例输出 Copy
2
0
6
3
5
提示
- 数据范围
对于30%的数据:N<=100
对于60%的数据:N<=1000
对于100%的数据:N<=50000,0<=K<N - 样例解释
第一天最多可以吃到两个苹果,可以去0或6,去0 第二天最多吃两个,去6 第三天最多吃一个,去3 第四天最多吃一个,去5
思路:长链刨分,找最长的链,将路上的权值加到叶子节点上,对叶子节点排序,输出.
//长链刨分
#include<bits/stdc++.h>
using namespace std;
const int N=50005;
int cnt;
int head[N],nxt[N*4],to[N*4],dis[N],len[N];
void add(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
//dfs1求深度,父亲,儿子,还有长度
int fa[N],dep[N],son[N],p[N];
int _top;
int stk[N];
void dfs1(int now,int father)
{
len[now]=1;
for(int i=head[now];i;i=nxt[i])
if(to[i]!=father)
{
dfs1(to[i],now);
if(len[to[i]]>len[son[now]] ||(len[son[now]]==len[to[i]]&& p[to[i]]<p[son[now]]))
son[now]=to[i];
}
if(!son[now])
{
stk[++_top]=now;
p[now]=now;
}
else p[now]=p[son[now]];
len[now]=len[son[now]]+1;
}
//dfs2 求距离
void dfs2(int now,int res,int father)
{
if(!son[now])
{
dis[now]=res;
return;
}
else dfs2(son[now],res+1,now);
for(int i=head[now];i;i=nxt[i])
{
if(to[i]!=father && to[i]!=son[now])
{
dfs2(to[i],1,now);
}
}
}
bool cmp(int a,int b)
{
if(dis[a]==dis[b])return a<b;
return dis[a]>dis[b];
}
int main()
{
int n,re;
scanf("%d%d",&n,&re);
for(int i=2;i<=n;i++)
{
int a;
scanf("%d",&a);
a++;
add(a,i);
add(i,a);
}
re++;
dfs1(re,0);
dfs2(re,1,0);
sort(stk+1,stk+1+_top,cmp);
printf("%d\n",re-1);
for(int i=1;i<=_top;i++)
printf("%d\n",stk[i]-1);
}