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 9
1 2 28
1 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...