D - 最安通勤ルート / Cheapest Commute Route Editorial by admin
Claude 4.6 Opus (Thinking)Overview
This is a problem where, given a weighted undirected graph, we need to find the shortest path from station \(1\) to station \(N\) and determine whether its fare is within the budget of \(K\) yen.
Analysis
Key insight: To find “the minimum total fare that is at most \(K\) yen,” it suffices to find the shortest path (the path with minimum total fare) from station \(1\) to station \(N\). If the shortest path’s fare is at most \(K\), that is the answer; if even the shortest path exceeds \(K\), then no other path can achieve a fare of \(K\) or less.
Naive approach (BFS, etc.): If all edge weights were the same, we could find the shortest path using breadth-first search (BFS). However, since the fare \(C_i\) differs for each route in this problem, BFS cannot correctly find the shortest path.
Solution: For shortest path problems on graphs with non-negative edge weights, Dijkstra’s algorithm is suitable. Since \(C_i \geq 1\), the non-negativity condition is satisfied, and Dijkstra’s algorithm works correctly.
Algorithm
Graph construction: Build an adjacency list from the input. Connect each pair of stations \(U_i, V_i\) with a bidirectional edge (with fare \(C_i\)).
Compute shortest distances using Dijkstra’s algorithm:
- Prepare a distance array
dist, initialized withdist[1] = 0and all others set to \(\infty\). - Insert
(0, 1)(distance \(0\), station \(1\)) into a priority queue (min-heap). - Repeatedly extract the vertex \(u\) with the minimum distance from the heap. For each adjacent vertex \(v\) of \(u\), if the distance via \(u\), \(d + c\), is less than
dist[v], update it and add it to the heap. - We can terminate early when vertex \(N\) is extracted (since
dist[N]is finalized at that point).
- Prepare a distance array
Judgment and output:
- If
dist[N]\(\leq K\), outputdist[N]. - If
dist[N]is \(\infty\) (unreachable) or exceeds \(K\), output-1.
- If
Concrete example (when \(N=3, M=3, K=5\)):
Edges: 1-2 (fare 3), 2-3 (fare 2), 1-3 (fare 6)
- Path \(1 \to 2 \to 3\): fare \(3 + 2 = 5\) (\(\leq K\))
- Path \(1 \to 3\): fare \(6\) (\(> K\))
- The shortest is \(5\), which is within the budget, so the answer is \(5\).
Complexity
- Time complexity: \(O((N + M) \log N)\)
- This is the standard complexity of Dijkstra’s algorithm. Each heap operation takes \(O(\log N)\), and at most one heap insertion is performed per edge.
- Space complexity: \(O(N + M)\)
- The adjacency list uses \(O(N + M)\), the distance array uses \(O(N)\), and the heap contains at most \(O(M)\) elements.
Implementation Notes
Fast input using
sys.stdin.buffer.read(): In Python, standard input reading tends to be slow, so bulk reading is used for speedup.Duplicate check when extracting from the heap: The check
if d > dist[u]: continueprevents reprocessing vertices that have already been finalized with a shorter distance. Without this, the time complexity degrades.Early termination: Since the shortest distance is finalized when vertex \(N\) is extracted from the heap,
if u == N: breakeliminates unnecessary exploration.Since the fare \(C_i\) can be up to \(10^9\) and the number of edges can be up to \(2 \times 10^5\), the shortest distance can be on the order of \(10^{14}\). In Python, there is no integer overflow, so no special handling is needed. However, in other languages, you need to use
long longtypes.Source Code
import heapq
import sys
def main():
input_data = sys.stdin.buffer.read().split()
idx = 0
N = int(input_data[idx]); idx += 1
M = int(input_data[idx]); idx += 1
K = int(input_data[idx]); idx += 1
graph = [[] for _ in range(N + 1)]
for i in range(M):
U = int(input_data[idx]); idx += 1
V = int(input_data[idx]); idx += 1
C = int(input_data[idx]); idx += 1
graph[U].append((V, C))
graph[V].append((U, C))
# Dijkstra's algorithm from node 1 to node N
INF = float('inf')
dist = [INF] * (N + 1)
dist[1] = 0
pq = [(0, 1)]
while pq:
d, u = heapq.heappop(pq)
if d > dist[u]:
continue
if u == N:
break
for v, c in graph[u]:
nd = d + c
if nd < dist[v]:
dist[v] = nd
heapq.heappush(pq, (nd, v))
if dist[N] <= K:
print(dist[N])
else:
print(-1)
main()
This editorial was generated by claude4.6opus-thinking.
posted:
last update: