ABC192 E - Train
備忘録
問題
回答
import sys import os import math import bisect import itertools import collections import heapq import queue import array import time import datetime # 時々使う # import numpy as np # from decimal import Decimal, ROUND_HALF_UP # from scipy.sparse.csgraph import csgraph_from_dense, floyd_warshall # 再帰の制限設定 sys.setrecursionlimit(10000000) def ii(): return int(sys.stdin.buffer.readline().rstrip()) def il(): return list(map(int, sys.stdin.buffer.readline().split())) def it(): return tuple(map(int, sys.stdin.buffer.readline().split())) def fl(): return list(map(float, sys.stdin.buffer.readline().split())) def iln(n): return [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)] def iss(): return sys.stdin.buffer.readline().decode().rstrip() def sl(): return list(map(str, sys.stdin.buffer.readline().decode().split())) def isn(n): return [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)] def lcm(x, y): return (x * y) // math.gcd(x, y) # MOD = 10 ** 9 + 7 MOD = 998244353 INF = float('inf') def dijkstra(N, start, graph): dist = [INF] * N # 各頂点までの距離を保持する配列 dist[start] = 0 # 開始始点の頂点は距離をゼロとする visited = [0] * N # 各頂点の訪問状態を保持する配列[0: 未訪問, 1: 訪問済み] heap = [(0, start)] # 距離と始点頂点(自分自身への移動距離はゼロ) heapq.heapify(heap) # 距離と頂点の情報を距離で優先度付きキューとする while heap: # 頂点uとuに到達するまでの距離 min_cost, u = heapq.heappop(heap) # さらに小さい距離で既に到達済みの場合はcontinue if dist[u] < min_cost: continue visited[u] = 1 # 頂点uを訪問済みにする # グラフの情報から接する頂点と移動距離を順に処理 for cost, k, v in graph[u]: if visited[v] != 1: # 移動時のコスト計算で # 移動可能な時間まで待機するようにする q = math.ceil(dist[u]/k) * k + cost if q < dist[v]: # 未到達かつ小さい距離で移動できる場合には # 距離の更新と優先度付きキューに(距離, 頂点)の情報を追加 dist[v] = q heapq.heappush(heap, (dist[v], v)) return dist def main(): if os.getenv("LOCAL"): sys.stdin = open("input.txt", "r") N, M, X, Y = il() graph = [[] for _ in range(N)] for _ in range(M): a, b, t, k = il() graph[a-1].append((t, k, b-1)) graph[b-1].append((t, k, a-1)) dist = dijkstra(N, X-1, graph) print(-1 if dist[Y-1] == INF else dist[Y-1]) if __name__ == '__main__': main()
考え方
各都市を頂点、電車を辺としてグラフに置き換えます。
あとは頂点X
から頂点Y
までの最短距離を求める問題です。
ダイクストラ法を用いるとグラフの最短距離を求めることが出来ます。
ただし、注意点として、時刻がK
の倍数のときだけ電車に乗ることが出来ます。
したがって、頂点から異なる頂点に移動するときのコストの計算に現在時刻からK
の倍数になるまでの待機時間の考慮が必要となります。