求最小生成樹演算法——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...