D - チェックポイントラリー / Checkpoint Rally 解説 by admin
Claude 4.5 OpusOverview
This problem asks for the shortest time to visit \(K\) specified checkpoints in order from the start point and reach the goal. We use Dijkstra’s algorithm to compute the shortest path for each segment.
Analysis
Problem Breakdown
In this problem, we need to travel in the following order: $\(1 \rightarrow P_1 \rightarrow P_2 \rightarrow \cdots \rightarrow P_K \rightarrow N\)$
In other words, the total travel time is the sum of the shortest distances for each segment.
Issues with the Naive Approach
If we run Dijkstra’s algorithm for each segment, we would need \(K+1\) executions of Dijkstra’s algorithm. However, if the same checkpoint appears multiple times (e.g., \(P_1 = P_3\)), we would repeat the same computation wastefully.
Key Optimization
Important observation: There are at most \(K+2\) checkpoints (start, \(K\) intermediate points, goal). Since \(K \leq 10\), there are at most \(12\) checkpoints.
Therefore, if we run Dijkstra’s algorithm once from each unique checkpoint, we can immediately determine the shortest distance between any two points.
Concrete Example
For example, if \(K=2\) and the visit order is \(1 \rightarrow 3 \rightarrow 5 \rightarrow N\): - Run Dijkstra’s algorithm from each of checkpoints \(1, 3, 5, N\) - Calculate \(\text{dist}[1][3] + \text{dist}[3][5] + \text{dist}[5][N]\)
Algorithm
- Graph Construction: Create an adjacency list from the \(M\) input roads
- Checkpoint List Creation: Create \([1, P_1, P_2, \ldots, P_K, N]\)
- Dijkstra’s Algorithm Execution: Run Dijkstra’s algorithm from each checkpoint in the list (after removing duplicates) to compute shortest distances to all vertices
- Total Travel Time Calculation: Sum up the shortest distances between consecutive checkpoints
- Unreachability Check: If any segment is unreachable (distance is \(\infty\)), output
-1
checkpoints = [1, P_1, P_2, ..., P_K, N]
total_time = dist[1][P_1] + dist[P_1][P_2] + ... + dist[P_K][N]
Complexity
Time Complexity: \(O((K+2) \cdot (M + N) \log N)\)
- One Dijkstra execution: \(O((M + N) \log N)\)
- Number of executions: At most \(K+2\) times (after removing duplicates)
- Since \(K \leq 10\), effectively \(O(M \log N)\)
Space Complexity: \(O((K+2) \cdot N + M)\)
- Distance array from each checkpoint: \(O(N)\) for at most \(K+2\) checkpoints
- Graph adjacency list: \(O(M)\)
Implementation Notes
Utilizing Duplicate Removal: Use
set(checkpoints)to avoid running Dijkstra’s algorithm multiple times from the same checkpointInitial Distance Value: Use
float('inf')to correctly identify unreachable casesDictionary-based Distance Management: Store the shortest distance array from each checkpoint
cpindist_from[cp]for efficient accessEarly Termination: Output
-1and terminate as soon as any segment is found to be unreachable
Source Code
import heapq
from collections import defaultdict
def dijkstra(graph, start, n):
dist = [float('inf')] * (n + 1)
dist[start] = 0
pq = [(0, start)]
while pq:
d, u = heapq.heappop(pq)
if d > dist[u]:
continue
for v, w in graph[u]:
if dist[u] + w < dist[v]:
dist[v] = dist[u] + w
heapq.heappush(pq, (dist[v], v))
return dist
def main():
import sys
input = sys.stdin.readline
N, M, K = map(int, input().split())
graph = defaultdict(list)
for _ in range(M):
u, v, t = map(int, input().split())
graph[u].append((v, t))
graph[v].append((u, t))
P = list(map(int, input().split()))
# List of vertices that need to be visited: 1, P_1, P_2, ..., P_K, N
checkpoints = [1] + P + [N]
# Calculate shortest distances from each checkpoint
dist_from = {}
for cp in set(checkpoints):
dist_from[cp] = dijkstra(graph, cp, N)
# Calculate minimum time along the route
total_time = 0
for i in range(len(checkpoints) - 1):
src = checkpoints[i]
dst = checkpoints[i + 1]
d = dist_from[src][dst]
if d == float('inf'):
print(-1)
return
total_time += d
print(total_time)
if __name__ == "__main__":
main()
This editorial was generated by claude4.5opus.
投稿日時:
最終更新: