D - 配達ルートの最適化 / Optimizing Delivery Routes Editorial by admin
GPT 5.2 HighOverview
This problem asks you to find the shortest travel time from point \(1\) to point \(N\) in a situation where speed regulations double the travel time on certain roads. If the destination is unreachable, output \(-1\).
Analysis
- This problem is a “shortest path in a weighted undirected graph.”
The weight (travel time) of each road is given, and only the regulated roads have their weights changed from \(W_i \rightarrow 2W_i\), so ultimately we just need to find the shortest distance on a “graph with finalized weights.” - Naively “enumerating all paths and finding the shortest” is impossible. The number of paths grows exponentially, and with \(N, M \le 2 \times 10^5\), this is far too slow.
- Additionally, breadth-first search (BFS) can only guarantee correct shortest distances when “all edge weights are equal.” In this problem, \(W_i\) can be up to \(10^9\) and differs per edge, so BFS would result in WA.
- Since all weights are non-negative (\(W_i \ge 1\), so \(2W_i\) is also non-negative), we can use the standard Dijkstra’s algorithm.
As a concrete example, if a road’s normal travel time is \(5\) minutes and it is subject to regulation, that road’s weight becomes \(10\) minutes. The essence of the problem is to determine the actual weight of every road this way, then solve it as a shortest path problem.
Algorithm
- Store the information \((U_i, V_i, W_i)\) for road \(i\) from the input.
- Record the regulated road numbers \(C_1,\dots,C_K\) in a boolean array
regulated(whether road \(i\) is subject to regulation). - Build an adjacency list:
- Set the actual weight of road \(i\) as
$\( w = \begin{cases} 2W_i & (\text{regulated})\\ W_i & (\text{otherwise}) \end{cases} \)$ and add it as an undirected edge to bothg[U_i]andg[V_i].
- Set the actual weight of road \(i\) as
- Use Dijkstra’s algorithm to find the shortest distances
distfrom source \(1\).- Insert
(distance, vertex)into a priority queue (heap), and finalize vertices in order of minimum distance. - If a popped element
(d, u)is outdated information (d != dist[u]), skip it.
- Insert
- If
dist[N]was never updated, the destination is unreachable, so output \(-1\); otherwise, outputdist[N].
Complexity
- Time complexity: \(O((N+M)\log N)\)
(Dijkstra’s algorithm: each edge relaxation is effective at most once, and each heap operation costs \(\log N\)) - Space complexity: \(O(N+M)\)
(adjacency list, distance array, heap)
Implementation Notes
Since the input is large, we read it all at once with
sys.stdin.buffer.read()andsplit()it for fast processing.The regulated road numbers are \(1\)-indexed, so we subtract \(1\) to convert them to \(0\)-indexed to match the array.
The shortest distance can become extremely large (\(W_i \le 10^9\), and there can be many edges), so we use a sufficiently large value like
INF = 10**30.As a standard technique in Dijkstra’s algorithm, we skip outdated elements popped from the heap using
if d != dist[u]: continue, reducing unnecessary exploration.Source Code
import sys
import heapq
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
if not data:
return
idx = 0
N, M, K = data[idx], data[idx + 1], data[idx + 2]
idx += 3
U = [0] * M
V = [0] * M
W = [0] * M
for i in range(M):
U[i] = data[idx]
V[i] = data[idx + 1]
W[i] = data[idx + 2]
idx += 3
regulated = [False] * M
for _ in range(K):
c = data[idx] - 1
idx += 1
regulated[c] = True
g = [[] for _ in range(N + 1)]
for i in range(M):
w = W[i] * 2 if regulated[i] else W[i]
u = U[i]
v = V[i]
g[u].append((v, w))
g[v].append((u, w))
INF = 10**30
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, w in g[u]:
nd = d + w
if nd < dist[v]:
dist[v] = nd
heapq.heappush(pq, (nd, v))
ans = dist[N]
print(-1 if ans >= INF else ans)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.2-high.
posted:
last update: