AGC009-B:Tournament
問題
https://beta.atcoder.jp/contests/agc009/tasks/agc009_b
考え方
木DPだが、遷移が重要。今ある親 u から 4 個の子 (v_1, v_2, v_3, v_4)をもつ部分木の場合を考える。ある頂点の深さを cost[p] としておく。

このとき、トーナメントの割当としては以下のようになる。

u は v_1, v_2, v_3, v_4 のいずれとも試合をするが、このとき u の深さが最適に(一番浅く)なるときは、深い場所に一番浅い頂点をもつように、すなわち cost[v_1] >= cost[v_2] >= cost[v_3] >= cost[v_4] となるように割り当てるのが最適である。
このとき u の深さ cost[u] は cost[v_k] を降順にソートしておいて cost[u] = cost[v_k] + k+1 となる
List<Integer>[] g;
public void solve(int testNumber, InputReader in, PrintWriter out) {
int n = in.nextInt();
g = new ArrayList[n];
g = Stream.generate(ArrayList::new).limit(n).toArray(List[]::new);
for (int i = 1; i < n; i++) {
int a = in.nextInt()-1;
g[a].add(i);
}
int ans = dfs(0);
out.println(ans);
}
int dfs(int now) {
List<Integer> list = new ArrayList<>();
for (int next : g[now]) {
list.add(dfs(next));
}
Collections.sort(list, Comparator.reverseOrder());
int ret = 0;
for (int i = 0; i < list.size(); i++) {
ret = Math.max(ret, i+1 + list.get(i));
}
return ret;
}
ポイント
- 実験して遷移を考える