D - 登山ルートの選択 / Selection of a Mountain Climbing Route 解説 by admin
GPT 5.2 HighOverview
Among all routes from point \(1\) to point \(N\) that pass through at most \(K\) points, we want to minimize the maximum elevation along the route (the highest elevation). We determine “Is it possible to reach the destination with the highest elevation at most some value?” and minimize this value using binary search.
Analysis
Key Observations
- Keeping the highest elevation at most \(x\) means “using only points with elevation \(H_i \le x\)” to travel from point \(1\) to point \(N\).
- The constraint that the number of points visited is at most \(K\) translates to at most \(K-1\) edges (number of moves), since number of points = number of edges + 1.
- Additionally, the problem requires “not visiting the same point twice (simple path),” but a shortest path (minimum number of edges) is always a simple path. Therefore, it suffices to check the shortest distance using BFS to determine “is it reachable with at most \(K-1\) edges?” (there is no need to handle the simple path condition separately).
Why a Naive Approach Is Difficult
- The candidates for the highest elevation can be up to \(10^9\), making brute-force enumeration infeasible.
- Furthermore, directly enumerating all routes (simple paths) leads to combinatorial explosion.
Solution Strategy
- The candidates for the highest elevation can actually be restricted to “the elevation of some point” (the optimal value always coincides with some \(H_i\)).
- Therefore, we binary search over the array of elevations sorted in ascending order, and for each candidate check:
- “In the subgraph consisting only of points with elevation \(\le x\), is the shortest distance from \(1 \to N\) at most \(K-1\)?” using BFS.
Algorithm
- Remove duplicates from the elevation array \(H\), sort in ascending order, and create
heights_sorted. - Prepare a feasibility function
feasible(x):- If \(H_1 > x\) or \(H_N > x\), immediately return False (the start or destination cannot be used).
- Perform BFS, but forbid visiting points with elevation \(> x\).
- Maintain distance (number of edges)
dist, and return True ifdist[N] \le K-1. - During BFS, do not extend further from vertices whose distance has already reached \(K-1\) (pruning).
- First, if the destination is unreachable even with the maximum candidate (
heights_sorted[-1]), the answer is-1. - Otherwise, binary search over
heights_sortedto find the minimum \(x\) for whichfeasiblereturns True, and output it.
Complexity
- Time complexity: \(O((N+M)\log N)\) (BFS is \(O(N+M)\), and binary search runs at most \(\log(\text{number of unique elevations}) \le \log N\) times)
- Space complexity: \(O(N+M)\) (adjacency list and distance array for BFS)
Implementation Notes
Note that the number of visited points \(K\) translates to an edge limit of
max_edges = K-1.The “simple path” condition requires no additional handling, since the shortest path returned by BFS is always a simple path.
The following pruning techniques are effective within
feasible:- Do not proceed further from a vertex where
du == max_edges(extending further would exceed the limit). - Return immediately upon reaching point \(N\) (early termination).
- Do not proceed further from a vertex where
Since the input scale is on the order of \(10^5\) and \(2\times 10^5\), use
sys.stdin.buffer.readlineand adjacency lists for speedup.Source Code
import sys
from collections import deque
def main():
input = sys.stdin.buffer.readline
N, M, K = map(int, input().split())
H = list(map(int, input().split()))
adj = [[] for _ in range(N)]
for _ in range(M):
u, v = map(int, input().split())
u -= 1
v -= 1
adj[u].append(v)
adj[v].append(u)
heights_sorted = sorted(set(H))
target = N - 1
max_edges = K - 1
def feasible(x: int) -> bool:
if H[0] > x or H[target] > x:
return False
dist = [-1] * N
dq = deque([0])
dist[0] = 0
while dq:
u = dq.popleft()
du = dist[u]
if u == target:
return du <= max_edges
if du == max_edges:
continue
for v in adj[u]:
if dist[v] != -1:
continue
if H[v] > x:
continue
dist[v] = du + 1
if v == target:
return dist[v] <= max_edges
dq.append(v)
return False
if not feasible(heights_sorted[-1]):
print(-1)
return
lo, hi = 0, len(heights_sorted) - 1
while lo < hi:
mid = (lo + hi) // 2
if feasible(heights_sorted[mid]):
hi = mid
else:
lo = mid + 1
print(heights_sorted[lo])
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.2-high.
投稿日時:
最終更新: