문제 링크
- http://icpc.me/17518
사용 알고리즘
- Centroid Decomposition
시간복잡도
- $O(N \log^2 N)$
풀이
루비 5 문제를 푸는 사람이라면 모두가 알고 있을 사실 2가지를 짚고 넘어가겠습니다.
- 트리 $T$의 정점 $i$에서 $j$로 가는 경로의 거리 $D(i, j)$는 $T$의 Centroid Tree $C_T$에서 $i, j$의 LCA $L = LCA_{C_T}(i, j)$에 대해 $D(L, i) + D(L, j)$입니다.
- $D(i, j)$는 $T$의 Centroid Tree $C_T$에서 $i, j$의 공통 조상 $P$에 대해 $D(i, j) \leq D(P, i) + D(P, j)$를 만족합니다.
이 두 사실을 잘 기억하고 있으면 풀이는 상당히 쉽게 나옵니다.
$T_1, T_2$의 Centroid Tree $C_{T_1}, C_{T_2}$를 만듭시다. $C_{T_1}$에서 어떤 정점 $v$를 루트로 하는 서브 트리 내에서의 정답을 모두 구하는 방법을 알아봅시다.
서브 트리 내에서 $v$의 자손 $c$의 정답은, 서브 트리 내에 있는 또 다른 정점 $x$에 대해 $D_1(c, v) + D_1(v, x) + D_2(v, x)$ 이하가 됩니다. 만약 $C_{T_2}$에서 $x$의 모든 조상 $y$를 순회한다면 $D_1(c, v) + D_1(v, x) + D_2(v, y) + D_2(y, x)$를 계산해도 됩니다.
그러므로 $C_{T_1}$에서 $v$의 자손 $x$에 대해 $C_{T_2}$에서 $x$의 조상 $y$에 $D_1(v, x) + D_2(y, x)$의 최솟값을 저장한 뒤, 다시 $C_{T_1}$에서 $v$의 자손 $c$마다 $C_{T_2}$에서 $c$의 조상 $p$를 순회하면서 정답을 갱신하면 됩니다. (($p$에 저장된 최솟값)$+ D_1(c, v) + D_2(p, c)$ 갱신)
$C_{T_1}$에서 $v$를 루트로 하는 서브 트리의 크기를 $S_v$라고 할 때, $v$의 서브 트리 내에서의 정답은 $O(S_v \log N)$ 시간에 구할 수 있습니다. Centroid Tree에서 $\sum S_v \in O(N \log N)$이므로 $O(N \log^2 N)$에 문제를 풀 수 있습니다.
전체 코드
1 |
|