最小生成樹Prim演算法

2022-06-01 10:57:13 字數 1770 閱讀 2656

求最小生成樹演算法——prim

例題:演算法:時間複雜度 : $o(n^2)$

$\text$ 演算法主要是用到貪心的思想,假設我們有兩個集合 $a$ 和 $b$,$a$ 集合表示最小生成樹集合(及 $a$ 集合中的點都在最小生成樹中),$b$ 集合表示非最小生成樹集合(及 $b$ 集合中的點都不在最小生成樹中)。一開始,我們可以隨便將乙個點放入集合 $a$,然後我們選擇到最小生成樹中距離最小的點放入 $a$ 集合(前提是最小 $\&$$\&$ 當前點在 $b$ 集合),然後用當前點更新其他在 $b$ 集合中的點到 $a$ 集合的距離。以此類推,迴圈 $n$ 次之後(一共有 $n$ 個點,所以 $n$ 次之後,$b$ 集合為空,所有點都在 $a$ 集合),就可得到最小生成樹。

我們可以記錄每個點到最小生成樹集合中的最小距離,記為$dis_i$ —— 第 $i$ 個點到最小生成樹集合中的最小距離(注意:是到最小生成樹集合的最短距離,不是到起點)。然後我們還需知道乙個點是否在最小生成樹集合中,於是我們用 $vis_i$ 表示 $i$ 是否在最小生成樹集合中(在 $a$ 集合,還是在 $b$ 集合)。當然我們可以用 $f_$ 來記錄第 $i$ 個點到第 $j$ 個點的距離。

1. 初始化所有點都在 $b$ 集合中,所有點到 $a$ 集合中的距離都為$0$;

2. 隨機選擇乙個點(選 $1$ 即可),並將當前點到最小生成樹的距離為 $0$;

3. 重複 $n$ 次以下步驟(及把所有點都放到a集合)

定義變數 $minn$ 表示每次搜到的到最小生成樹集合的最小距離(初始化為 $inf$),$k$ 表示搜到的最小值的編號

搜尋 $b$ 集合中到 $a$ 集合的最小值

標記搜到的點在 $a$ 集合

$ans$ 來累加當前點到最小生成樹集合的距離

通過當前搜到的點 $k$,來更新其他點到最小生成樹集合的最短距離

4. 得到最小生成樹,邊權之和在 $ans$ 裡

示意圖:

定義最大值(0x3f3f3f3f是乙個很大的數)

3using

namespace

std;

4int n, m, dis[1001], vis[1001], f[1001][1001], ans;//

dis[i]表示第i個點到最小生成樹集合的最小值(及到最小生成樹中任意點的最小值), vis[i]表示第i個點是否在最小生成樹中, f[i][j]表示從第i個點到達第j個點的最小值(無法到達就賦inf), ans記錄最小生成樹邊權

5void prim(int s)621

}22if(!k)//

沒有點在最小生成樹中了(這個也可以判斷圖是否連通,如果k沒有值,就代表圖沒有連通,因為最小生成樹中點的數量一定是n(生成樹的定義就是用n - 1條邊,使得n個點能互相到達))

2326 vis[k] = 1;

27 ans += dis[k];

28for(int j = 1; j <= n; ++j)

2934}35

}36return;37

}38 int main()

3947 prim(1);//

從1開始就好了

48 printf("%d"

, ans);

49return0;

50 }

最小生成樹(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...