문제
풀이
문제를 일반적인 형태로 바꾸어 봅시다.
문제에서 주어지는 waypoint끼리의 관계를 $1$이 루트인 트리로 나타낼 수 있습니다.
waypoint는 정점, ski run은 간선으로 생각합니다.
우리가 해결해야 하는 문제는 $1$에서 다른 정점까지의 경로 중 $s < d$인 간선을 최대 $c$개만 포함하는 경로의 $e$의 합의 최댓값을 구하는 것입니다.
$c = 0$
$c = 0$인 쿼리만 들어온다고 생각해 봅시다.
$D_i$를 정점 $i$에서 루트까지 $d$의 최댓값이라 합시다.
$c = 0$이므로 경로에서 어떤 간선도 $s$를 넘으면 안 됩니다.
따라서 $D_i$를 미리 정렬한 다음 이분 탐색을 통해서 $D_k \le s < D_{k + 1}$을 만족하는 $k$를 찾습니다. 이때 $D_i$는 정렬되었으므로 $k$는 정점 번호가 아님에 유의합시다.
이제 $i = 1$부터 $k$까지의 경우만 고려해주면 되고, 이는 전처리로 $O(N)$에 구해둘 수 있습니다.
$c \neq 0$
$c \neq 0$인 경우도 비슷하게 해결할 수 있습니다.
최대 $c$개의 간선은 $s$를 넘어도 상관없으므로 $c + 1$번째로 큰 간선의 가중치만 $s$를 넘지 않으면 됩니다.
$D_{ic}$를 정점 $i$에서 루트까지 $d$ 중 $c + 1$번째로 작은 값이라 정의합시다.
그렇다면 똑같이 $D_{ic}$를 미리 정렬한 다음 이분 탐색을 통해서 해결할 수 있습니다.
총 시간 복잡도는 $O(N + M\log N)$입니다.
코드
$E_i$를 루트에서 $i$번 정점까지 가는 경로의 $e$의 합으로 정의하고 $DE = (D_i, E_i)$ 순서쌍으로 관리했습니다.
1 | |