最小生成樹(mst):權值最小的生成樹。乙個有 n 個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有 n 個結點,並且有保持圖連通的最少的邊。最小生成樹可以用kruskal(克魯斯卡爾)演算法或prim(普里姆)演算法求出。
1.在乙個有n個點的連通圖中,邊的數量一定大於等於n-1,而等於n-1這種情況,就是連通圖的最小生成樹。2.n個點用n-1條邊連通,形成的圖只可能是樹。
因此,要在乙個連通圖中找到最小生成樹,需要滿足:
1.相同端點的邊優先取長度小的邊
2.用n-1條邊連線n個點(沒有迴路)
kruskal演算法就是以邊為核心的演算法,它每次用一條邊連線兩個點(其中乙個點在樹中,另乙個點在樹外,或者兩個點都在樹外),只要邊的數量達到了n-1,那麼最小生成樹就形成了。
要滿足條件一,只需要用sort按邊長排序即可
要滿足條件二(沒有迴路),即兩個已經連通的點不需要再連線。這裡我們可以用並查集的根結點的性質判斷兩個點是否已經在同一連通圖中。
舉個例子,現在有n個村子,要修建公路連通所有村子(只需保證從a村能到達b村即可,途中可經過c村),給你m組某兩個村子間的可修建方案距離,問:至少要修建多少千公尺的公路?
先輸入兩個整數n、m。(n表示有村子數量,m表示有方案數量。)然後在接下來的m行輸入三個整數a,b,l,表示在該方案中,a村子和b村子的修建公路長度為l。
樣例輸入:
4 51 2 4
1 3 3
1 3 2
3 4 1
2 3 5
樣例輸出
7
首先,輸入有五種方案
對應的是
① 1 2 4
② 1 3 3
③ 1 3 2
④ 3 4 1
⑤ 2 3 5
我們先按兩兩村子間的方案距離排序,得到
④ 3 4 1
③ 1 3 2
② 1 3 3
① 1 2 4
⑤ 2 3 5
接下來就是連通的過程,顯然④肯定要取,它的兩個端點都在樹外,並且距離最小。然後看③,③中有端點1、3,其中3在樹內,1在樹外,也滿足條件。然後看②,①在樹內,③也在樹內,這時取了這組方案就會產生迴路,因此這種方案不能取。再看①,1在樹內,2在樹外,滿足條件。這時我們已經用④③①三條邊連線了四個村子,即滿足了用n-1條邊連線n個結點
的情況,最小生成樹已經產生,可以直接跳過下面的方案。
最終答案就是1+2+4=7
**實現如下:
#include
#include
using
namespace std;
#define n 100005
int pre[n]
;struct line
p[n]
;int
find
(int x)
//查詢x的根節點並且完成路徑壓縮
bool
cmp(line a, line b)
intmain()
if(ct == n -1)
//如果邊的數量已經達到了n-1條,直接break退出
break;}
cout << ans << endl;
return0;
}
kruskal 最小生成樹
include include 產生隨機數組用 include 同上 include using namespace std 1 帶權邊的類myarc class myarc bool operator const myarc arc myarc myarc int beginvex,int end...
最小生成樹Kruskal
最小生成樹有兩個特點,乙個是保證了所有邊的和是最小值,另乙個是保證了所有邊中的最大值最小。struct edge bool friend operator edge a,edge b 構邊 vectoredge int id max int mini void initial void input ...
最小生成樹(kruskal)
kruskal演算法 1 記graph中有v個頂點,e個邊 2 新建圖graphnew,graphnew中擁有原圖中相同的e個頂點,但沒有邊 3 將原圖graph中所有e個邊按權值從小到大排序 4 迴圈 從權值最小的邊開始遍歷每條邊 直至圖graph中所有的節點都在同乙個連通分量中 if 這條邊連線...