結果
問題 |
No.3111 Toll Optimization
|
ユーザー |
![]() |
提出日時 | 2025-04-20 14:13:40 |
言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
結果 |
AC
|
実行時間 | 1,684 ms / 5,000 ms |
コード長 | 3,793 bytes |
コンパイル時間 | 549 ms |
コンパイル使用メモリ | 12,288 KB |
実行使用メモリ | 68,444 KB |
最終ジャッジ日時 | 2025-04-20 14:14:36 |
合計ジャッジ時間 | 38,325 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 70 |
ソースコード
import heapq import sys # 標準入力の高速化 (必要な場合) # input = sys.stdin.readline def solve(): """問題を解くメイン関数""" N, M, K = map(int, sys.stdin.readline().split()) # M本の橋のコストをリストとして読み込む edges_cost = list(map(int, sys.stdin.readline().split())) # グラフを隣接リストで表現 # graph[u] には (v, cost) のタプルのリストが入る # u: 現在の町, v: 隣接する町, cost: 橋のコスト graph = [[] for _ in range(N)] for i in range(M): # 橋の両端の町を読み込む u, v = map(int, sys.stdin.readline().split()) # 0-indexed に調整 u -= 1 v -= 1 # i番目の橋のコストを取得 cost = edges_cost[i] # 無向グラフなので両方向のエッジを追加 graph[u].append((v, cost)) graph[v].append((u, cost)) # 距離配列の初期化 # dist[i][k] は、町iにクーポンをk枚使って到達するための最小コスト # 十分に大きい値 (無限大) で初期化する INF = float('inf') dist = [[INF] * (K + 1) for _ in range(N)] # 優先度付きキュー (最小ヒープ) の初期化 # 要素は (現在のコスト, 現在の町, 使ったクーポン数) のタプル pq = [(0, 0, 0)] # スタート地点 (町1 = 0-indexed, コスト0, クーポン使用0枚) dist[0][0] = 0 # スタート地点のコストを0に設定 # ダイクストラ法の開始 while pq: # 現在最もコストが小さい状態を取り出す current_cost, u, k_used = heapq.heappop(pq) # 取り出した状態のコストが、記録されている最小コストより大きい場合は、 # より効率的な経路がすでに見つかっているのでスキップする if current_cost > dist[u][k_used]: continue # 現在の町uから移動可能な隣接町vへの遷移を調べる for v, cost in graph[u]: # --- ケース1: クーポンを使わずに橋を渡る --- new_cost_no_coupon = current_cost + cost # より小さいコストで町vに到達できる場合 if new_cost_no_coupon < dist[v][k_used]: # 最小コストを更新 dist[v][k_used] = new_cost_no_coupon # 新しい状態を優先度付きキューに追加 heapq.heappush(pq, (new_cost_no_coupon, v, k_used)) # --- ケース2: クーポンを使って橋を渡る --- # クーポンがまだ残っている場合 (k_used < K) if k_used < K: # クーポンを使うので、コストは現在のコストのまま (current_cost) new_cost_with_coupon = current_cost # クーポン使用後の状態 (町v, クーポン使用数 k_used + 1) のコストを確認 # より小さいコストで到達できる場合 if new_cost_with_coupon < dist[v][k_used + 1]: # 最小コストを更新 dist[v][k_used + 1] = new_cost_with_coupon # 新しい状態を優先度付きキューに追加 heapq.heappush(pq, (new_cost_with_coupon, v, k_used + 1)) # 町N (0-indexedでは N-1) に到達するための最小コストを計算 # クーポンを0枚からK枚まで使った場合のコストのうち、最も小さいものを探す min_cost_to_N = min(dist[N - 1]) # 結果の出力 # 最小コストがINFのままなら到達不可能 if min_cost_to_N == INF: print(-1) else: print(min_cost_to_N) # 関数を実行 solve()