ログインしてください。
Official
D - 街歩きと通行料 / City Walk and Tolls Editorial by admin
GPT 5.2 High概要
道路の移動時間に加えて「交差点を通るたびに通行料がかかる」グラフで、交差点 \(1\) から \(N\) までの最小コスト経路を求める問題です。通行料は出発点・到着点でも支払います。
考察
- これは本質的に最短経路問題です。
ただし通常の最短経路は「辺(道路)に重み」があるのに対し、この問題では「頂点(交差点)にもコスト(通行料)」があります。 - 素朴に「全ての経路を列挙して最小を取る」ような方法は、経路数が爆発して \(N, M \le 2\times 10^5\) では到底間に合いません。
- 重要な気づきは、頂点コストは“次に到達する頂点に入るコスト”として辺の遷移に組み込めることです。
交差点 \(u\) から道路 \((u,v)\)(時間 \(w\))で \(v\) に行くとき、追加コストは $\( w + \text{toll}[v] \)$ となります。 - 出発点の通行料も必要なので、初期値は $\( \text{dist}[1] = \text{toll}[1] \)\( としてスタートします(到着点の通行料も、どこかから \)N\( に入るときに \)\text{toll}[N]$ が加算されるので自然に処理できます)。
このようにすると、すべての重みが非負(\(w\ge 1\), \(\text{toll}\ge 0\))なので ダイクストラ法がそのまま使えます。
アルゴリズム
- 隣接リストで無向グラフを構築する。
- 各交差点の通行料配列
tollを用意し、該当しない頂点は \(0\) にする。 - ダイクストラ法を行う。
dist[i]= 交差点 \(1\) から \(i\) へ到達する最小コスト
- 初期化:
dist[1] = toll[1] - 優先度付きキューから頂点
uを取り出し、各隣接vについて $\( \text{nd} = \text{dist}[u] + w(u,v) + \text{toll}[v] \)$ で緩和する。
dist[N]を出力する。
(例)もし \(1 \to 3\) に時間 \(5\)、通行料が \(\text{toll}[1]=2, \text{toll}[3]=4\) なら、コストは \(2 + 5 + 4 = 11\) になります。これは「最初に 1 を通る」+「道路」+「3 を通る」をそのまま足した形です。
計算量
- 時間計算量: \(O((N+M)\log N)\)(ダイクストラ法+優先度付きキュー)
- 空間計算量: \(O(N+M)\)(グラフ・距離配列・キュー)
実装のポイント
出発点の通行料を忘れずに
dist[1] = toll[1]とする(ここが \(0\) だと WA)。ダイクストラ法では典型的に、優先度付きキューから取り出した
(d, u)についてd != dist[u]なら古い情報なのでスキップします。u == Nが確定した時点(キューから取り出した時点)でbreakしても正しく、少し高速化できます(コードでも実施)。ソースコード
import sys
import heapq
def main():
data = list(map(int, sys.stdin.buffer.read().split()))
it = iter(data)
N = next(it); M = next(it); K = next(it)
g = [[] for _ in range(N + 1)]
for _ in range(M):
u = next(it); v = next(it); w = next(it)
g[u].append((v, w))
g[v].append((u, w))
toll = [0] * (N + 1)
for _ in range(K):
l = next(it); c = next(it)
toll[l] = c
INF = 10**30
dist = [INF] * (N + 1)
dist[1] = toll[1]
pq = [(dist[1], 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 + toll[v]
if nd < dist[v]:
dist[v] = nd
heapq.heappush(pq, (nd, v))
print(dist[N])
if __name__ == "__main__":
main()
この解説は gpt-5.2-high によって生成されました。
posted:
last update: