D - バス路線の乗り換え / Bus Route Transfers Editorial by admin
gpt-5.3-codex概要
「1回の乗車で、同じ路線内のどのバス停へも移動できる」という性質を使い、バス停を頂点とした BFS で最小乗車回数を求める問題です。
ただし同じ路線を何度も展開すると遅くなるため、各路線は一度だけ使うのがポイントです。
考察
重要な観察は次の2つです。
- あるバス停 \(u\) に乗車回数 \(d\) で到達しているとき、
\(u\) を通る任意の路線 \(r\) に1回乗れば、その路線上のすべてのバス停へ \(d+1\) 回で行ける。 - 路線 \(r\) を一度展開(その路線上の全バス停への緩和)した後、
別のバス停から再び同じ路線 \(r\) を展開しても、新しい情報は基本的に増えず無駄になりやすい。
素朴に「各バス停から、そのバス停を通る全路線、さらにその路線上の全バス停」を毎回たどると、同じ路線を何度も走査してしまい、最悪で非常に重くなります。
そこで used_route[r] を持ち、各路線を最初に使った1回だけ処理します。
これにより、各バス停は必要なときにキューへ入り、各路線は1回だけ全停留所をなめるので、全体を制約内で高速に処理できます。
アルゴリズム
- 入力から以下を作る。
routes[r]: 路線 \(r\) が通るバス停のリストstop_to_routes[s]: バス停 \(s\) を通る路線番号のリスト(逆引き)
dist_stop[s]を「バス停 \(s\) への最小乗車回数」として、初期値を \(\infty\)、dist_stop[S]=0。- キューで BFS を行う。
- バス停
uを取り出す。u==Tならその距離を出力して終了。 uを通る各路線rについて、未使用なら使用済みにする。- 路線
r上の各バス停vに対し、dist_stop[v] > dist_stop[u] + 1なら更新してキューへ入れる。
- バス停
- BFS が終わっても
Tに到達しなければ-1。
この BFS は「1回の乗車」をちょうど1コストとして層状に広がるため、最初に T に到達した回数が最小です。
計算量
- 時間計算量: \(O\!\left(N + \sum K_i\right)\)(厳密には入力読込分を含めて同程度)
- 空間計算量: \(O\!\left(N + M + \sum K_i\right)\)
(理由)
各路線は used_route により高々1回だけ展開され、各展開でその路線の停留所数ぶんだけ処理するため、路線側の総処理は \(\sum K_i\) 回です。
実装のポイント
stop_to_routes(停留所→路線)を作っておくと、現在地から乗れる路線を即座に列挙できます。used_routeが最重要。これがないと同じ路線を何度もなめて遅くなります。S==Tの場合も、BFS開始直後にu==Tで0を正しく返せます。距離配列は十分大きい値 (
INF) で初期化し、if dist_stop[v] > nd:で更新判定するのが安全です。ソースコード
import sys
from collections import deque
def main():
input = sys.stdin.readline
N, M, S, T = map(int, input().split())
routes = []
stop_to_routes = [[] for _ in range(N + 1)]
for i in range(M):
data = list(map(int, input().split()))
k = data[0]
stops = data[1:]
routes.append(stops)
for s in stops:
stop_to_routes[s].append(i)
INF = 10**18
dist_stop = [INF] * (N + 1)
used_route = [False] * M
q = deque()
dist_stop[S] = 0
q.append(S)
while q:
u = q.popleft()
d = dist_stop[u]
if u == T:
print(d)
return
for r in stop_to_routes[u]:
if used_route[r]:
continue
used_route[r] = True
nd = d + 1
for v in routes[r]:
if dist_stop[v] > nd:
dist_stop[v] = nd
q.append(v)
print(-1)
if __name__ == "__main__":
main()
この解説は gpt-5.3-codex によって生成されました。
posted:
last update: