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

2021-08-04 06:31:32 字數 1657 閱讀 2048

僅有粗略的演算法解釋。

給定乙個圖,有n個點m個邊,要求找到這個圖的最小生成樹

輸入輸出格式

輸入:

第一行:n,m

下面m行:x,y,v,表示點xy之間有乙個長度是v的點。

輸出:

第一行:最小生成樹的總長度

下面n行:最小生成樹(第i個點和那些點有邊?)

樣例

輸入:

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

1: 2

2: 1 3

3: 9 6 4 2

4: 3 5

5: 4

6: 7 3

7: 8 6

8: 7

9: 3

樣例解釋

在8和7之間加乙個長度是1的邊

在7和6之間加乙個長度是2的邊

在9和3之間加乙個長度是2的邊

在2和1之間加乙個長度是4的邊

在6和3之間加乙個長度是4的邊

在4和3之間加乙個長度是7的邊

在3和2之間加乙個長度是8的邊

在5和4之間加乙個長度是9的邊

把所有邊按照邊長排序

從1到m列舉邊,如果邊的兩端點不在乙個集合中,便加上這條邊,然後把這兩個端點堆在乙個集合中(並查集優化)

所有點都在乙個集合中(生成樹完成),無法繼續加邊,演算法結束,輸出結果。

#include

#include

#include

#include

#include

#include

using

namespace

std;

int n,m,an[23333],ans=0,k,frog;

struct po a[10000];

struct tp;

vector

tree[23333];//陣列模擬鄰接表

bool cmp(po a,po b)

}void myunion(int x,int y)

void dadd(int a,int b,int v)

int main()

for(int i=1; i<=n; i++)

an[i]=i;

//演算法開始:

sort(a+1,a+k+1,cmp);

for(int i=1; i<=k; i++)

}//演算法結束,輸出。

cout

cout

0;}

如果想找到最大生成樹,只需改變排序順序即可,本質上是貪心的思想。

克魯斯卡爾求最小生成樹

處理何種問題 求解最小生成樹,適合點多邊少的無向圖。以證明,放心用 效能 時間複雜度為o e loge e為邊的個數。原理 貪心策略 實現步驟 1 設乙個有n個頂點的聯通網路為g v,e 最初先構造乙個只有n個頂點,沒有邊的非連通圖t 圖中的每乙個頂點自成乙個連通分量。2 在e中選擇一條具有最小權值...

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

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 最大邊數...