最小生成樹演算法 Prim演算法和Kruskal演算法

2021-09-24 03:22:38 字數 1740 閱讀 2116

prim演算法理解,可以看這篇文章

其實就是每次從當前樹中外選取乙個離樹最近且不構成環的點,同時sum記錄權值,然後把這個點加入樹中,直到所有節點都被訪問過,最小生成樹生成成功,輸出最小生成樹的權值和。

下面是prim演算法的板子,和最短路有點相似,也稱為「加點法」。

//最小生成樹prim演算法

#include#define inf 0x3f3f3f3f

using namespace std;

const int maxn = 110;

int n,m;

int g[maxn][maxn];

int prim()

mst[1]=0;//起始點進樹

for(int i = 2;i<=n;i++){

int minn=inf,minid=0;

for(int j = 2;j<=n;j++)//遍歷lowcost陣列,查詢最小值

if(minn>lowcost[j]&&lowcost[j]!=0)

minn=lowcost[minid=j];

// printf("%d-%d=%d\n",mst[minid],minid,minn);

lowcost[minid]=0;//查詢到的最短的點進樹

sum+=minn;

for(int j=2;j<=n;j++){//節點進樹後更新外面的點到樹的最短距離並且mst記錄其起點

if(g[minid][j]其實也可以用乙個visited陣列來標記是否被訪問過。

kruskal演算法(基於貪心思想和並查集的實現)

關於演算法的理解可以看這篇部落格

不過上面部落格的**實現比較複雜。

關於並查集的理解可以看這篇文章

其實演算法很好理解,就是先把圖中所有邊按照權值從小到大給他們排個序(貪心),然後每次取一條邊,判斷邊的起點和終點是否在乙個連通分量裡面,如果不在就合併,(這裡關鍵在於連通分量的查詢和合併),直到構成一棵最小生成樹。

一談到貪心,我們就不能簡單的去用,還要能證明,不然說不定就錯了(qaq,就像01揹包一樣)

下面給出偽**的實現

把所有邊排序,記第i小的邊為e[i](i<=1#includeusing namespace std;

int p[110],w[110],r[110],u[110],v[110];

//第i條邊的兩個端點序號和權值分別儲存在u[i],v[i]和w[i]中

//排序後第i小的序號儲存在r[i]中(間接排序,排序的是物件的代號而不是其本身)

int n,m;

bool cmp(const int i ,const int j)//間接排序函式

{ return w[i]然後就是各種習題的練習,下面給出一些經典的題和題解。

poj 1251jungle roads ——

poj1251題解

poj 1287 networking ——

poj1287題解

poj 2031 building a space station——

poj2031題解

poj 2421 constructing roads ——

poj2421題解

zoj1586qs network —— zoj1586題解

poj1789truck history ——

poj1789題解

poj2349arctic network——

poj2349題解

poj1751highways——poj1751題解

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