結果
| 問題 | No.3653 Space-Time Courier |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-07-25 12:16:46 |
| 言語 | PyPy3 (7.3.17) |
| 結果 |
AC
|
| 実行時間 | 3,093 ms / 4,000 ms |
| + 942µs | |
| コード長 | 2,683 bytes |
| 記録 | |
| コンパイル時間 | 257 ms |
| コンパイル使用メモリ | 96,616 KB |
| 実行使用メモリ | 118,880 KB |
| 最終ジャッジ日時 | 2026-08-28 21:10:01 |
| 合計ジャッジ時間 | 27,964 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge3_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 28 |
ソースコード
import sys
from heapq import heappush, heappop
from collections import deque
def solve():
# 入力をすべて読み込む
input_data = sys.stdin.read().split()
if not input_data:
return
N = int(input_data[0])
M = int(input_data[1])
# 頂点の重み P
P = [0] * (N + 1)
for i in range(1, N + 1):
P[i] = int(input_data[1 + i])
adj = [[] for _ in range(N + 1)]
idx = N + 2
for _ in range(M):
u = int(input_data[idx])
v = int(input_data[idx+1])
t = int(input_data[idx+2])
adj[u].append((v, t))
idx += 3
# 1. SPFA (Bellman-Fordのキューによる定数倍高速化版) を用いてポテンシャル h を求める
# 超頂点からの距離初期値をすべて 0 とみなす
h = [0] * (N + 1)
in_queue = [True] * (N + 1)
q = deque(range(1, N + 1))
while q:
u = q.popleft()
in_queue[u] = False
hu = h[u]
for v, t in adj[u]:
if h[v] > hu + t:
h[v] = hu + t
if not in_queue[v]:
q.append(v)
in_queue[v] = True
# 2. 辺の重みを非負に変換する (Johnson's rule)
adj_pos = [[] for _ in range(N + 1)]
for u in range(1, N + 1):
hu = h[u]
for v, t in adj[u]:
adj_pos[u].append((v, t + hu - h[v]))
# 事前計算で (P[j] + h[j]) を保持しておく
P_plus_h = [0] * (N + 1)
for i in range(1, N + 1):
P_plus_h[i] = P[i] + h[i]
INF = 10**18
min_cost = INF
min_count = 0
# 3. 各頂点を始点として Dijkstra 法を実行
for i in range(1, N + 1):
dist = [INF] * (N + 1)
dist[i] = 0
hq = [(0, i)]
while hq:
d, u = heappop(hq)
if d > dist[u]:
continue
for v, w in adj_pos[u]:
nd = d + w
if dist[v] > nd:
dist[v] = nd
heappush(hq, (nd, v))
# 4. コストの最小値を計算
base = P[i] - h[i]
for j in range(1, N + 1):
if i == j or dist[j] == INF:
continue
# 元の距離に基づくコスト計算
cost = dist[j] + base + P_plus_h[j]
if cost < min_cost:
min_cost = cost
min_count = 1
elif cost == min_cost:
min_count += 1
print(f"{min_cost} {min_count}")
if __name__ == '__main__':
solve()