【问题描述】
我们高大的老班举起了有半个他那么高的三角板,说:“你们想象一下——”
于是你就陷入了想象……
有一棵n 个点的树,每个叶子节点上都有一个人,他们按照每秒钟走一条边的
速度向树根(节点1)前进。
你可以运用k 次想象之力,让某一个节点(除了根节点)上的所有人瞬间(耗
时为0)转移到这个节点的父亲上。
你想知道最少需要多少时间,所有人可以到达根节点。
【输入格式】
从文件imagine.in 中读入数据。
输入的第一行包含两个整数n,k,含义见问题描述。
接下来n-1 行,第i 行一个整数fai,表示节点i 的父亲为fai。
【输出格式】
输出到文件imagine.out 中。
输出一行一个整数,表示所有人到达根节点最少需要的时间。
【样例1 输入】
6 2
12224
【样例1 输出】
1
【样例1 说明】
一开始,在节点3,5,6 上分别有一个人,我们称他们为A,B,C。
时刻0,在节点6 运用想象之力,A 到达节点4。
第1 秒,A,B,C 走到节点2。
时刻1,在节点2 运用想象之力,A,B,C 到达节点1,即目的地。
共用时1 秒。
【样例2 输入】
3 2
1
2
【样例2 输出】
0
【样例2 说明】
一开始只有节点3 上有一个人。
时刻0,在节点3 运用想象之力,这个人到达节点2;
此时仍然为时刻0,在节点2 运用想象之力,这个人到达节点1。
数据范围:n<=5e5,k<=n
题解:
看到题目是求可行解的最值问题,故想到二分+判定答案。那么如果已知时间,即一起向上走的步数,如何判断是否可行呢?问题在于k个想象之力要在何时用。
我们可以将时间的流逝一秒看做所有非空的点构成的树的叶子节点清空,并填上它们的父亲,而使用想象之力就是将一个节点清空,并填上它的父亲,最后要将根节点外的所有节点清空。已知时间,那么应该在时间流逝完后再从下至上将所有非空节点清空,因为若在时间流逝玩之前清空一个节点,那么后面可能这个节点会被它的孩子填上(根除外),故这样是最优的。所以可以看做清空若干次叶子,然后再清空最后的树(根除外),那么需要用的想象之力就是走完后的点数减一,所以就可以判定了。而由于枚举一起走的步数时可顺便维护所剩下节点数,故一边枚举一边判定,可行时退出即可。