Official

G - Hidden Weights Editorial by sotanishy


グラフの各連結成分について,そのうちの \(1\) つの頂点に書き込む値を決めると,その連結成分内のすべての頂点に書き込むべき値が確定します.ある頂点の値を決めると,それと辺でつながっている頂点の値が決まる,というのが連鎖的に起こるからです.よって,頂点を順番に見ていって,まだ値が確定していない頂点があったら,その頂点の値を適当な値(たとえば \(0\))に固定し,その頂点と連結なすべての頂点の値を連鎖的に確定させる,ということを繰り返すことで,この問題を解くことができます.

このような処理の実装は,深さ優先探索 (DFS)幅優先探索 (BFS)により行えます.DFS による実装例を以下に示します.時間計算量は,\(O(N+M)\) です.

# 入力を読み込む
N, M = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
    u, v, w = map(int, input().split())
    u -= 1
    v -= 1
    G[u].append((v, w))
    G[v].append((u, -w))

visited = [False] * N  # 値が確定しているかどうか
ans = [0] * N  # 書き込む値
for i in range(N):
    # すでに値が確定しているならばスキップ
    if visited[i]:
        continue
    # 頂点 i の値を 0 に確定し,探索を始める
    st = [i]
    visited[i] = True
    while st:
        # いま頂点 u にいる
        u = st.pop()
        # 頂点 u に隣接する頂点 v を調べる
        for v, w in G[u]:
            if not visited[v]:
                # まだ頂点 v の値が確定していないならば,頂点 u の値と整合的になるように,頂点 v の値を確定させる
                visited[v] = True
                ans[v] = ans[u] + w
                st.append(v)
print(*ans)

posted:
last update: