Official

D - 街歩きと通行料 / City Walk and Tolls Editorial by admin

DeepSeek V3

Overview

This problem is a shortest path problem on a graph consisting of intersections and roads, where we need to minimize the total cost considering both the travel time of roads and the tolls at intersections.

Analysis

As a naive approach, if we use the standard Dijkstra’s algorithm with only the travel time of each road as the cost, we cannot properly handle the tolls at intersections. Since a toll is charged each time an intersection is passed through, simply adding the toll to the edge weights does not yield correct cost calculations.

The key observation is that a toll is incurred exactly once upon entering each intersection. In other words, when intersection v is first reached, we need to pay the toll \(C_v\) for that intersection. Based on this property, in Dijkstra’s cost calculation, when moving from the current intersection to the next intersection, we can correctly handle this by adding the toll of the next intersection in addition to the movement cost (travel time of the road).

Algorithm

We apply Dijkstra’s algorithm with the following steps:

  1. Represent the graph as an adjacency list
  2. Record the toll for each intersection in an array tolls (intersections without toll areas have a toll of 0)
  3. Initialize the distance array dist, and set the cost of the starting point (intersection 1) to tolls[1] (the toll at the departure point)
  4. Using a priority queue, calculate the movement cost from the current intersection to the next intersection:
    • New cost = current cost + travel time of the road + toll of the next intersection
  5. Update if this new cost is smaller than the current minimum cost
  6. The minimum cost is obtained when the destination (intersection \(N\)) is reached

Complexity

  • Time complexity: \(O((N + M) \log N)\)
    • This is the standard complexity of Dijkstra’s algorithm. Each node and edge is processed at most once, and priority queue operations take \(\log N\)
  • Space complexity: \(O(N + M)\)
    • Memory usage for the graph’s adjacency list and distance array

Implementation Notes

  • Initialize the array so that the toll for intersections without toll areas is 0

  • Use a large number (\(10^{18}\)) as infinity to prevent overflow

  • For efficient use of the priority queue, skip entries whose cost does not match the current minimum value

  • Terminate early when the destination is reached to avoid unnecessary computation

    Source Code

import heapq
import sys

def main():
    data = sys.stdin.read().split()
    if not data:
        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)); w = int(next(it))
        graph[u].append((v, w))
        graph[v].append((u, w))
    
    tolls = [0] * (n+1)
    for _ in range(k):
        l = int(next(it)); c = int(next(it))
        tolls[l] = c
    
    INF = 10**18
    dist = [INF] * (n+1)
    dist[1] = tolls[1]
    
    heap = [(dist[1], 1)]
    
    while heap:
        d, node = heapq.heappop(heap)
        if d != dist[node]:
            continue
        if node == n:
            break
            
        for neighbor, weight in graph[node]:
            new_cost = d + weight + tolls[neighbor]
            if new_cost < dist[neighbor]:
                dist[neighbor] = new_cost
                heapq.heappush(heap, (new_cost, neighbor))
                
    print(dist[n])

if __name__ == "__main__":
    main()

This editorial was generated by deepseekv3.

posted:
last update: