题意:https://codeforces.com/contest/1739/problem/D
思路:首先很显然我们要二分去求答案,那么我们考虑如何check,首先如果我们从上往下去切的操作数是大于等于从下往上切的,所以我们从下往上切,一旦该顶点的子树最大高度大于二分值,那么我们就切一刀,然后该点高度-二分值。
/*keep on going and never give up*/
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define int long long
typedef pair<int, int> pii;
#define lowbit(x) x&(-x)
#define endl '\n'
#define wk is zqx ta die
vector<int> pl[200005];
int dep[200005];
int n, k;
int sum = 0, res = 0;
int cost;
void dfs(int x, int fa) {
int mx = 0;
for (auto g : pl[x]) {
if (g == fa) {
continue;
}
dfs(g, x);
mx = max(mx, dep[g]);
}
dep[x] = mx + 1;
if (dep[x] >= cost && fa != 1 && x != 1) {
res++;
dep[x] -= cost;
}
}
bool check(int x) {
cost = x;
res = 0;
dfs(1, 0);
if (res <= k) {
return true;
} else {
return false;
}
}
signed main() {
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
pl[i].clear();
}
for (int i = 2; i <= n; i++) {
int fa;
cin >> fa;
pl[fa].push_back(i);
}
int l = 1;
int r = n;
int ans;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
cout << ans << endl;
}
return 0;
}