D - 配達ルートの最短時間 / Shortest Time for Delivery Route 解説 by admin
DeepSeek V3Overview
This is a problem of finding the shortest path from a distribution center (point 1) through a relay station (point K) to the final destination (point N).
Analysis
This problem requires finding a route from point 1 → point K → point N. A naive approach would be the Floyd-Warshall algorithm, which computes shortest paths between all pairs of points. However, since N can be as large as 200,000, the O(N³) time complexity makes this infeasible.
The key observation is that the route can be decomposed into two parts: “point 1 → point K” and “point K → point N.” By computing the shortest path for each part individually and summing them, we obtain the overall shortest path.
Algorithm
We apply Dijkstra’s algorithm twice (or three times): 1. Compute the shortest distances from point 1 to all other points 2. Compute the shortest distances from point K to all other points 3. Compute the shortest distances from point N to all other points (in practice this is unnecessary, since running Dijkstra from point K is sufficient to obtain the distance from point K to point N)
In the actual implementation, we compute: - dist1[k]: the shortest distance from point 1 → point K - distK[n]: the shortest distance from point K → point N - The answer is dist1[k] + distK[n]
If either route does not exist (i.e., the distance is infinity), then the overall route does not exist either, so we output -1.
Complexity
- Time complexity: \(O((N + M) \log N)\) (running Dijkstra’s algorithm twice)
- Space complexity: \(O(N + M)\) (for the graph representation and distance arrays)
Implementation Notes
The Dijkstra implementation uses a heap (priority queue) to efficiently update shortest distances
Initial distance values are set to a sufficiently large value (10¹⁸) to detect unreachable points
The graph is represented as an adjacency list to reduce memory usage
Since each road is bidirectional, edges are added in both directions
Source Code
import heapq
import sys
def main():
data = sys.stdin.read().split()
if not data:
print(-1)
return
it = iter(data)
n = int(next(it)); m = int(next(it)); k = int(next(it))
graph = [[] for _ in range(n+1)]
for _ in range(m):
u = int(next(it)); v = int(next(it)); c = int(next(it))
graph[u].append((v, c))
graph[v].append((u, c))
def dijkstra(start):
dist = [10**18] * (n+1)
dist[start] = 0
heap = [(0, start)]
while heap:
d, node = heapq.heappop(heap)
if d != dist[node]:
continue
for neighbor, cost in graph[node]:
new_d = d + cost
if new_d < dist[neighbor]:
dist[neighbor] = new_d
heapq.heappush(heap, (new_d, neighbor))
return dist
dist1 = dijkstra(1)
distK = dijkstra(k)
distN = dijkstra(n)
if dist1[k] == 10**18 or distK[n] == 10**18:
print(-1)
else:
print(dist1[k] + distK[n])
if __name__ == "__main__":
main()
This editorial was generated by deepseekv3.
投稿日時:
最終更新: