クルトンのプログラミング教室

Pythonの使い方やPythonを使った競技プログラミングの解法などを解説しています。

Pythonで理解する蟻本「2-5 最小全域木問題1(プリム法)」(p.100)

この記事は「プログラミングコンテストチャレンジブック第2版」(蟻本)の
「2-5 最小全域木問題1(プリム法)」(p.100)
のコードをPythonで書き直したものとなっています。

入力


V:頂点数\\E:辺数\\頂点s_iと頂点t_iの間に重みc_iの無向辺が存在する(1\leq{i}\leq{E})


V\,E\\s_1\,t_1\,c_1\\:\\s_E\,t_E\,c_E

入力例

f:id:kuruton456:20201201145758p:plain


7 9
0 1 2
0 4 10
1 2 1
1 3 3
1 5 7
3 5 1
3 6 5
4 5 5
5 6 8


蟻本に載っているコード(O(|V|^2))

INF = float('inf')

V, E = map(int,input().split())    # Vは頂点数、Eは辺数
cost = [[INF] * V for _ in range(V)]    # cost[u][v]は辺e=(u,v)のコスト(存在しない場所はINF)
mincost = [INF] * V    # 集合Xからの辺の最終コスト
used = [False] * V    # 頂点iがXに含まれているか

for _ in range(E):
    s, t, c = map(int,input().split())
    cost[s][t] = c
    cost[t][s] = c

def prim():
    mincost[0] = 0
    res = 0
    
    while True:
        v = -1
        # Xに属さない頂点のうちXからの辺のコストが最小になる頂点を探す
        for u in range(V):
            if not used[u] and (v == -1 or mincost[u] < mincost[v]):
                v = u
        
        if v == -1:
            break
        used[v] = True    # 頂点vをXに追加
        res += mincost[v]    # 辺のコストを加える
        
        for u in range(V):
            mincost[u] = min(mincost[u], cost[v][u])
        
    return res

res = prim()

print(res)

実行結果

17

優先度付きキューを使った解法(O(|E| log |V|))

# 優先度付きキューをインポートする
import heapq

INF = float('inf')

V, E = map(int,input().split())    # Vは頂点数、Eは辺数
cost = [[INF] * V for _ in range(V)]    # cost[u][v]は辺e=(u,v)のコスト(存在しない場所はINF)
used = [False] * V    # 頂点iがXに含まれているか

for _ in range(E):
    s, t, c = map(int,input().split())
    cost[s][t] = c
    cost[t][s] = c

def prim():
    res = 0
    q = [[0, 0]]
    
    while True:
        v = -1
        MIN = INF
        # Xに属さない頂点のうちXからの辺のコストが最小になる頂点を探す
        while len(q) != 0:
            c, u = heapq.heappop(q)
            if not used[u] and (v == -1 or c < MIN):
                v = u
                MIN = c
                break
        
        if v == -1:
            break
        used[v] = True    # 頂点vをXに追加
        res += c    # 辺のコストを加える
        
        for u in range(V):
            if cost[v][u] != INF:
                heapq.heappush(q, [cost[v][u], u])
        
    return res

res = prim()

print(res)

実行結果

17