最小生成樹(Prim Kruskal)

2021-10-02 15:38:13 字數 1926 閱讀 1709

kruskal演算法(加邊法)

思路:

首先對邊的權值從小到大進行排序,而後遍歷檢視每一條邊,迴圈以下步驟:

1)若該邊兩端頂點分屬不同連通分量,則將此邊加入,之後將其兩端頂點合併為同乙個連通分量;

code:

#includeusing

namespace

std;

const

int maxn=1000;//

最大邊數

int n,m;//

n個頂點,m條邊

struct

node

}g[maxn],t[maxn];

void

kruskal()

,vs1,vs2,sum=0,q=0

; sort(g,g+m);//

對邊的權從小到大排序

for(int i=0;i<=n;i++)//

表示各頂點自成乙個連通分量

f[i]=i;

for(int i=1;i<=m;i++)

}if(q!=n-1)cout<<"

該圖不連通

"

}int

main()

可用並查集判斷邊的兩個頂點是否已屬於同一連通分量:

void init(intn)}

intget(int

x)int merge(int u,int

v)

return0;

}

prim演算法(加點法)

思路:

①需建立乙個輔助陣列dis維護已選取加入的點到其餘各個頂點的邊的最小權值。

②需建立乙個標記陣列標記哪個頂點已選取加入。

首先選取任意乙個頂點加入,建立上述的dis陣列,標記該頂點已選取加入,之後迴圈以下步驟n-1次:

(1)遍歷dis陣列找其中記錄的邊權值最小且未被選取的點加入,標記該點已選取,連線該邊的兩點;

(2)更新維護dis陣列。

code:

#includeusing

namespace

std;

const

int maxn=1000

;const

int inf=0x3f3f3f3f

;int

n,m,g[maxn][maxn];

void

init()

void

prim()

;

for(int i=0;i<=n;i++)//

選取任意乙個頂點加入,此處選擇編號1的點為第乙個加入的點

dis[i]=make_pair(1,g[1

][i]);

dis[

1].second=0

; book[

1]=1;//

標記已選取

for(int i=1;i<=n-1;i++)

}book[k]=1;//

標記已選取

u0=dis[k].first, v0=k, w0=min;

cout

<'

'<'

'輸出最小生成樹的邊

sum+=min;

dis[k].second=0

;

for(int u=0;u<=n;u++)

}cout

<<"

最小生成樹的邊權之和:

"}int

main()

prim();

return0;

}

(備註:因為有些測試用例的頂點編號為0~n-1,而有些是1~n,為了**對兩者都的適用,上述兩份**對頂點的for遍歷都是從0到n,故可輸入的頂點編號範圍為0~n。)

最小生成樹MST演算法(Prim Kruskal)

1 概念 乙個有 n 個結點的連通圖 的生成樹是原圖的極小連通子圖,且包含原圖中的所有 n 個結點,並且有保持圖連通的最少的邊,所謂乙個帶權圖的最小生成樹,就是原圖中邊的權值最小的生成樹,所謂最小是指邊的權值之和小於或者等於其它生成樹的邊的權值之和。2 性質 3 應用 例如 要在n個城市之間鋪設光纜...

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...