Kruskal演算法(貪心 並查集 最小生成樹)

2021-08-23 12:01:06 字數 3579 閱讀 1196

2023年04月16日 17:34:35

kruskal演算法的高效實現需要一種稱作並查集的結構。我們在這裡不介紹並查集,只介紹kruskal演算法的基本思想和證明,實現留在以後討論。

kruskal演算法的過程:

(1) 將全部邊按照權值由小到大排序。

(2) 按順序(邊權由小到大的順序)考慮每條邊,只要這條邊和我們已經選擇的邊不構成圈,就保留這條邊,否則放棄這條邊。

演算法 成功選擇(n-1)條邊後,形成乙個棵最小生成樹,當然如果演算法無法選擇出(n-1)條邊,則說明原圖不連通。

以下圖為例:

邊排序後為:

1 af 1

2 de 4

3 bd 5

4 bc 6

5 cd 10

6 bf 11

7 df 14

8 ae 16

9 ab 17

10 ef 33

演算法處理過程如下:

處理邊af,點a與點f不在同乙個集合裡,選中af。

處理邊de,點d與點e不在同乙個集合裡,選中de

處理邊bd,點b與點d不在同乙個集合裡,選中bd

處理邊bc,點b與點c不在同乙個集合裡,選中bc

處理邊cd,點c與點d在同乙個集合裡,放棄cd。

處理邊bf,點b與點f不在同乙個集合裡,選中bf。

至此,所有的點都連在了一起,剩下的邊df,ae,ab,ef不用繼續處理了,演算法執行結束。

kruskal演算法的證明。假設圖連通,我們證明krusal演算法得到一棵最小生成樹。我們假設kruskal演算法得到的樹是k (注意我們已經假設kruskal演算法一定可以得到生成樹)。假設t是一棵最小生成樹,並且k ≠t, k中顯然至少有一條邊。我們找到在k中,而不在t中最小權值的邊e。

把e加入t中,則形成乙個圈,刪掉這個圈中不在k中的邊f,得到新的生成樹t』。

f的存在性,如果全裡面所有的邊都在k中,則k包含圈,矛盾。

考慮邊權值關係:

(1) 若w(f) > w(e), 則t』的權值和小於t的權值和,與t是最小生成樹矛盾。

(2) 若w(f) < w(e), 說明kruskal演算法在考慮加入e之前先考慮了邊f,之所以沒加入f是因為f和之前加入的邊形成圈,之前加入的邊權值顯然不超過w(f) (因為加邊是從小到大的順序加入的),所以之前加入的邊權值一定小於w(e)。而根據e的定義,k中權值小於w(e)的邊都在t中,這說明t中的邊會和f構成圈,矛盾。

所以只能w(f) = w(e)。t』仍然是最小生成樹,而t』和k相同的邊多了一條。

這樣下去有限步之後,最終可以把t變為k,從而k也是最小生成樹。

最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。

輸入

第1行:2個數n,m中間用空格分隔,n為點的數量,m為邊的數量。(2 <= n <= 1000, 1 <= m <= 50000)

第2 - m + 1行:每行3個數s e w,分別表示m條邊的2個頂點及權值。(1 <= s, e <= n,1 <= w <= 10000)

輸出

輸出最小生成樹的所有邊的權值之和。
輸入示例

9 14

1 2 4

2 3 8

3 4 7

4 5 9

5 6 10

6 7 2

7 8 1

8 9 7

2 8 11

3 9 2

7 9 6

3 6 4

4 6 14

1 8 8

輸出示例

37
請選取你熟悉的語言,並在下面的**框中完成你的程式,注意資料範圍,最終結果會造成int32溢位,這樣會輸出錯誤的答案。

不同語言如何處理輸入輸出,請檢視下面的語言說明。

使用並查集和貪心思想。適合稀疏圖。

kruskal演算法實現:

#include #include #include using namespace std;

int parent[10];

int n,m;

int i,j;

struct edgeedges[10];

//初始化並查集

void ufset()

//查詢i的跟

int find(int i)

return temp;

}//合併兩個元素a,b

void merge(int a,int b)else

}void kruskal(){

int sumweight = 0;

int num = 0;

int u,v;

ufset();

for(int i=0; iw - e2->w;

int main() {

scanf("%d %d", &n, &m);

for(i=0; i測試資料:

7 91 2 281 6 10

2 3 16

2 7 14

3 4 12

4 5 22

4 7 18

5 6 25

5 7 24

輸出:

加入邊:1 6,權值: 10

加入邊:3 4,權值: 12

加入邊:2 7,權值: 14

加入邊:2 3,權值: 16

加入邊:4 5,權值: 22

加入邊:5 6,權值: 25

weight of mst is 99 */

Kruskal 演算法 並查集

需要注意的地方 將所有的邊權從小到大依次排序,按從小到大依次加入邊,每次對加入的邊進行如下操作 1.找出邊的兩點。2.判斷兩點的父親節點是在同乙個集合裡。3.如果不在同乙個集合,在將兩點所在的集合合併 union,且計數器 1 5.當計數器 n 1 總點數 時 停止查詢。此時只有乙個集合,該集合即為...

Kruskal演算法(貪心 並查集 最小生成樹)

kruskal演算法 克魯斯卡爾 演算法 的高效實現需要一種稱作並查集的結構。我們在這裡不介紹並查集,只介紹kruskal演算法的基本思想和證明,實現留在以後討論。kruskal演算法的過程 1 將全部邊按照權值由小到大排序。2 按順序 邊權由小到大的順序 考慮每條邊,只要這條邊和我們已經選擇的邊不...

Kruskal演算法的並查集實現

最小生成樹的kruskal演算法的偽 如下 w i 為邊的權值,u i v i 分別為邊的端點的下標 mst為最小生成樹的所有邊的結合 n為頂點的個數 m為邊的個數 將邊按權值排序w 0 w 1 w m 1 初始化每個頂點屬於不同的連通分量 for i 0 i include using names...