Reset K Edges (Codeforces 1739D)
Tags: Greedy, trees

You are given a rooted tree, consisting of $$$n$$$ vertices. The vertices are numbered from $$$1$$$ to $$$n$$$, the root is the vertex $$$1$$$.You can perform the following operation at most $$$k$$$ times:   choose an edge $$$(v, u)$$$ of the tree such that $$$v$$$ is a parent of $$$u$$$;  remove the edge $$$(v, u)$$$;  add an edge $$$(1, u)$$$ (i. e. make $$$u$$$ with its subtree a child of the root). The height of a tree is the maximum depth of its vertices, and the depth of a vertex is the number of edges on the path from the root to it. For example, the depth of vertex $$$1$$$ is $$$0$$$, since it's the root, and the depth of all its children is $$$1$$$.What's the smallest height of the tree that can be achieved?

Input: The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of testcases.The first line of each testcase contains two integers $$$n$$$ and $$$k$$$ ($$$2 \le n \le 2 \cdot 10^5$$$; $$$0 \le k \le n - 1$$$) — the number of vertices in the tree and the maximum number of operations you can perform.The second line contains $$$n-1$$$ integers $$$p_2, p_3, \dots, p_n$$$ ($$$1 \le p_i < i$$$) — the parent of the $$$i$$$-th vertex. Vertex $$$1$$$ is the root.The sum of $$$n$$$ over all testcases doesn't exceed $$$2 \cdot 10^5$$$.

Output: For each testcase, print a single integer — the smallest height of the tree that can achieved by performing at most $$$k$$$ operations.


Sample Inputs:
5
5 1
1 1 2 2
5 2
1 1 2 2
6 0
1 2 3 4 5
6 1
1 2 3 4 5
4 3
1 1 1

Sample Outputs:
2
1
5
3
1

Solution (Python):
import sys
input = sys.stdin.readline

def debug(func):

    def wrapper(*args, **kwargs):
        print('----------------')
        res = func(*args, **kwargs)
        print('----------------')
        return res
    return wrapper

def solve():
    (n, k) = list(map(int, input().split()))
    p = list(map(int, input().split()))
    p = [-1] + [x - 1 for x in p]

    def need_steps(depth):
        steps = 0
        h = [0] * n
        for i in range(n - 1, 0, -1):
            if h[i] == depth - 1 and p[i] != 0:
                steps += 1
            else:
                h[p[i]] = max(h[p[i]], h[i] + 1)
        return steps
    (l, r) = (0, n - 1)
    while l < r - 1:
        mid = (l + r) // 2
        if need_steps(mid) <= k:
            r = mid
        else:
            l = mid
    return print(r)
if __name__ == '__main__':
    for _ in range(int(input())):
        solve()

Solution (Python):
for _ in range(int(input())):
    (n, k) = map(int, input().split())
    arr = [-1, 0] + [int(i) for i in input().split()]
    (lr, r) = (1, n - 1)
    while lr < r:
        mid = (lr + r) // 2
        tot = 0
        h = [0] * (n + 1)
        for i in range(n, 1, -1):
            if h[i] == mid - 1 and arr[i] != 1:
                tot += 1
            else:
                h[arr[i]] = max(h[arr[i]], h[i] + 1)
        if tot <= k:
            r = mid
        else:
            lr = mid + 1
    print(lr)

Solution (Python):
for _ in range(int(input())):
    (n, k) = map(int, input().split())
    arr = [-1, 0] + [int(i) for i in input().split()]
    (lr, r) = (1, n - 1)
    while lr < r:
        mid = (lr + r) // 2
        tot = 0
        h = [0] * (n + 1)
        for i in range(n, 1, -1):
            if h[i] == mid - 1 and arr[i] != 1:
                tot += 1
            else:
                h[arr[i]] = max(h[arr[i]], h[i] + 1)
        if tot <= k:
            r = mid
        else:
            lr = mid + 1
    print(lr)