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也是最小生成樹。
n個點m條邊的無向連通圖,每條邊有乙個權值,求該圖的最小生成樹。
最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。
輸入
第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
貪心經典題目
問題描述 有n個人排隊到r個水龍頭去打水,他們裝滿水桶的時間為t1,t2,tn為整數且各不相等,應如何安排他們的打水順序才能使他們花費的時間最少?樣例輸入 4 2 4人打水,2個水龍頭 2 6 4 5 每個打水時間 先放 include include include using namespace...
貪心經典小題
題目背景 快noip了,yyy很緊張!題目描述 現在各大oj上有n個比賽,每個比賽的開始 結束的時間點是知道的。yyy認為,參加越多的比賽,noip就能考的越好 假的 所以,他想知道他最多能參加幾個比賽。由於yyy是蒟蒻,如果要參加乙個比賽必須善始善終,而且不能同時參加2個及以上的比賽。輸入輸出格式...
經典演算法之Kruskal演算法
生成最小生成樹,與prim演算法不同的是,prim是以頂點為關鍵來生成最小樹的,而kruskal是以邊為關鍵來生成最小數。1 將v個頂點,l條邊的圖g中所有的邊按權值大小從小到大排序,這一步可以直接用庫函式qsort或者sort。2 從權值小的邊開始依次選取,若選取的邊使生成樹t不形成迴路,則選之 ...