克魯斯卡爾求最小生成樹

2022-03-24 09:13:50 字數 1588 閱讀 1347

處理何種問題:求解最小生成樹,適合點多邊少的無向圖。(以證明,放心用)

效能:時間複雜度為o(e*loge),e為邊的個數。

原理:貪心策略

實現步驟

<1>設乙個有n個頂點的聯通網路為g(v,e),最初先構造乙個只有n個頂點,沒有邊的非連通圖t=,圖中的每乙個頂點自成乙個連通分量。

<2>在e中選擇一條具有最小權值的邊時,若該邊的兩個頂點落在不同的連通分量上,則將此邊加入到t中;否則,即這條邊的兩個頂點屬於同乙個連通分量,將此邊捨去(此後永不選用這條邊),重新選擇一條權值最小的邊。

<3>如此重複下去,直至選了(n-1)條有效邊,或者所有的頂點都在同一連通分量上為止。

備註:在此之前,本人對於網上給出的對於克魯斯卡爾的證明並不理解,只覺得這種貪心策略有bug,這次換乙個角度去理解這個演算法:<1>乙個孤立的點v要想連入最後的那個生成樹中,只需要找到在邊的中找連線v,且權值最小的那條邊即可,則可證明,權值最小的那條邊必然在最後的最小生成樹中;<2>對於已經連線的兩個孤立點,可看作乙個點,他們共享互相邊的性質。<3>一顆生成樹有且僅有n-1條邊。根據以上三點,即可推出克魯斯卡爾的正確性。只是在實現方式上有些難以理解。

輸入樣例解釋

4 6//頂點的個數,邊的個數

1 2 1//一條邊的兩個頂點和該邊上的權值

1 3 4

1 4 1

2 3 3

2 4 2

3 4 5

輸出樣例解釋

5//該無向圖的最小生成樹

**

#include#include#include#includeusing namespace std;

const int maxn=510;///最大頂點的數

const int maxm=251000;///最大邊數

int f[maxn];///並查集

struct edge

;edge edge[maxm];///儲存邊的信資訊,包括起點/終點/權值

int tal;///邊數,加邊前賦值為0

void addedge(int u,int v,int w)

bool cmp(edge a,edge b)///排序函式,邊按照權值從小到大排序

int find(int x)

int kruskal(int n)///傳入點數,返回最小生成樹的權值,如果不連通則返回-1

if(cnt==n-1)

break;

}if(cntreturn -1;///不連通

else

return ans;

}int main()

printf("%d\n",kruskal(n));

}return 0;

}/**

4 61 2 1

1 3 4

1 4 1

2 3 3

2 4 2

3 4 5

5*/

最小生成樹 克魯斯卡爾演算法

c node.h檔案 儲存頂點資訊 class c node c node c node c node p node c node c node c node c node char p data node.h檔案,儲存邊資訊 include class link node link node li...

最小生成樹( 克魯斯卡爾演算法)

name author date 01 12 14 20 17 description 最小生成樹 克魯斯卡爾演算法 關於並查集的演算法,參見 一種簡單而有趣的資料結構 並查集 include include define maxn 1000 最大頂點數量 define max 20000 最大邊數...

克魯斯卡爾 最小生成樹集錦

狀態是1的兩個分量直接聯通,然後套模板。include include include include include include include include include include using namespace std define maxn 1e 9 int pa 10000 ...