最小生成樹 Prim演算法

2021-08-31 03:30:16 字數 2370 閱讀 4685

我們要學習的第一種計算最小生成樹的方法是prim演算法,它的每一步都會為一棵生長中的樹新增一條邊。一開始這棵樹只有乙個頂點,然後會向它新增 v−1

v-1v−

1 條邊,每次總是將下一條連線樹中的頂點與不在樹中的頂點且權重最小的邊加入樹中。

prim演算法能夠得到任意加權無向圖的最小生成樹

每當我們向樹中新增了一條邊之後,也向樹中新增了乙個頂點。要維護乙個包含所有橫切邊的集合,就要將連線這個頂點和其他所有不在樹中的頂點的邊加入優先佇列。

注意:新加入樹中的頂點與其他已經在樹中的頂點連線的邊都失效了。

prim演算法的即時實現可以將這樣的邊從優先佇列中刪掉

延時實現將這些邊先留在優先佇列中,等到要刪除它們的時候再檢查邊的有效性。

具體演算法如下:

prim演算法的延時實現使用了一條優先佇列pq來儲存所有的橫切邊、乙個由頂點索引的陣列marked來標記樹的頂點、一條佇列mst來儲存最小生成樹的邊。

這種延時實現會在優先佇列中保留失效的邊。

和實現 深度優先搜尋dfs 和 廣度優先搜尋bfs 一樣,實現會在建構函式中計算圖的最小生成樹,這樣用例方法就可以用查詢類方法獲得最小生成樹的各種屬性。

/*

* 最小生成樹的prim演算法 (延時版本)

*/public

class

lazyprimmst

}//為樹新增乙個頂點v、將它標記為「已訪問」,並將所有連線v和未被標記頂點的邊加入優先佇列pq

private

void

visit

(edgeweightedgraph g,

int v)

}public iterable

edges()

}

要改進 lazyprimmst,可以嘗試從優先佇列中刪除失效的邊,這樣優先佇列就只含有樹頂點和非樹頂點之間的橫切邊,但其實還可以刪除更多的邊。

我們只在優先佇列中儲存每個非樹頂點w的一條邊:將它與樹中的頂點連線起來的權重最小的那條邊。將w和樹的頂點連線起來的其他權重較大的邊遲早都會失效,所以沒必要在優先佇列中儲存它們。

primmst類將lazypgrimmst中的 marked 和 mst 替換為兩個頂點索引的陣列edgetodistto。它們具有如下性質:

如果頂點v不在樹中但至少含有一條邊和樹相連,那麼edgeto[v]是將v和樹連線的最短邊,distto為這條邊的權重。

primmst會從優先佇列中取出一條邊v並檢查它的鄰接鍊錶中的每條邊 v-w。

如果w已經被標記過,那麼這條邊就已經失效了;

如果w不在優先佇列中、或 v-w 的權重小於目前已知的最小值 edgeto[w],**會更新陣列,將 v-w 作為將v和樹連線的最佳選擇。

* 最小生成樹的prim演算法 (即時版本)

*/public

class

primmst

}//將頂點v新增到樹中,更新資料

private

void

visit

(edgeweightedgraph g,

int v)}}

public iterable

edges()

}return mst;

}}

最小生成樹(prim演算法)

最小生成樹是資料結構中圖的一種重要應用,它的要求是從乙個帶權無向完全圖中選擇n 1條邊並使這個圖仍然連通 也即得到了一棵生成樹 同時還要考慮使樹的權最小。prim演算法要點 設圖g v,e 其生成樹的頂點集合為u。把v0放入u。在所有u u,v v u的邊 u,v e中找一條最小權值的邊,加入生成樹...

最小生成樹 Prim演算法

prim 演算法 以領接矩陣儲存 圖g bool b i 表示頂點i是否被訪問,初始化時候memset b,false,sizeof b b 0 value,表示從第0個節點開始。用value i 表示節點i到最小生成樹a中定點的最小距離。例如value 1 a 0 1 int sum記錄權值和 i...

最小生成樹 prim 演算法

一 演算法描述 假設存在連通帶權圖g v,e 其中最小生成樹為t,首先從圖中隨意選擇一點s屬於v作為起始點,並將其標記後加入集合u 中。然後演算法重複執行操作為在所有v屬於u,u屬於v u的邊 v0,u0 屬於e中找一條代價最小的邊並加入集合t,同時將u0併入u,直到u v為止。這是,t中必有n 1...