문제: BOJ 15292 - Journey from Petersburg to Moscow
아이디어 요약
- 핵심 변환(α 트릭): 임계값
α
를 두고 간선w
를 비용max(0, w−α)
로 바꾸면, 임의의 경로P
에 대해 \(k·α + \sum_{e\in P} \max(0, w_e - α)\) 의 최소값을 구하는 문제가 된다. 이 표현을α
에 대해 최소화하면P
에서 가장 비싼 간선k개
의 합과 같아진다. - 전역 최적화 교환: \(\min_P \min_α Φ_α(P) = \min_α \min_P Φ_α(P)\). 따라서 각
α
마다 변환된 가중치로 최단경로를 구한 뒤k·α
를 더하고, 모든 후보α
에 대해 최소를 취하면 전역 최적해가 된다. - 후보
α
집합:Φ_α
는 간선 가중치에서만 기울기가 바뀌므로α ∈ {0} ∪ {모든 w}
만 확인해도 충분하다. - 알고리즘: 각
α
에 대해 가중치max(0, w−α)
로 다익스트라를 수행해dist[n]
을 구하고,ans = min(ans, dist[n] + k·α)
를 갱신한다.
C++ 풀이
|
|
복잡도
α
후보 수 ≤m + 1 (가중치 종류 + 0)
- 각 다익스트라
O((n + m) log n)
→ 전체O((m + 1) · (n + m) log n)
- 제약
n, m ≤ 3000
에서 충분히 빠르게 동작
빌드/실행
- 빌드:
g++ -O2 -pipe -static -s -std=gnu++17 main.cpp -o main
- 실행:
./main < input.txt > output.txt