문제 링크
- https://atcoder.jp/contests/agc023/tasks/agc023_f
문제 출처
- AtCoder AGC 023 F번
사용 알고리즘
- 그리디
- 유니온 파인드
시간복잡도
- $O(N log N)$
풀이
트리의 각 정점 안에 $a_i$개의 0과 $b_i$개의 1이 있다는 정보를 저장해줍시다.
$N$개의 정점 중 $\frac {a_i}{b_i}$가 큰 정점을 $v$, $v$의 부모를 $p$라고 하면 $p$ 바로 뒤에 $v$가 오는 것이 최적이라는 것을 exchange argument를 이용해 증명할 수 있습니다. $b_i$가 0인 경우에는 $\frac {a_i}{b_i}$를 무한대로 정의해주면 됩니다.
이 성질을 이용해 그리디한 알고리즘을 사용할 수 있습니다.
$\frac {a_i}{b_i}$가 가장 큰 정점인 $v$를 그의 부모 $p$ 바로 다음에 나오는 것이 최적이라는 것을 증명했기 때문에, 트리에서 $v$와 $p$를 merge해줄 수 있습니다!
노드를 merge해줄 때 merge하면서 발생하는 inversion을 모두 계산해준다면, merge한 이후에는 같은 정점 안에 있는 숫자에 대해서는 inversion을 신경쓰지 않고 노드와 노드 사이의 inversion만 신경을 써주면 됩니다.
두 노드 $p$와 $v$를 merge해줄 때 발생하는 inversion은 $b_p * a_v$입니다.
노드를 $N-1$번 merge해주면서 inversion을 계산해주면 정답을 구할 수 있습니다.
노드를 merge한 정보를 union-find로 관리해주고, $\frac {a_i}{b_i}$가 가장 큰 정점을 고르는 것을 priority queue등의 자료구조로 관리해주면 $O(N log N)$에 문제를 풀 수 있습니다.
전체 코드
1 |
|