最小生成樹之Kruskal演算法

2021-08-14 09:12:30 字數 1630 閱讀 4884

最小生成樹

kruskal演算法描述:該演算法是基於貪心的思想得到的。首先我們把所有的邊按照權值先從小到大排列,接著按照順序選取每條邊,如果這條邊的兩個端點不屬於同一集合,那麼就將它們合併,直到所有的點都屬於同乙個集合為止。合併頂點可以利用並查集,換而言之,kruskal演算法就是基於並查集的貪心演算法。

kruskal演算法流程

1. 新建圖g,g中擁有原圖中相同的節點,但沒有邊;

2. 將原圖中所有的邊按權值從小到大排序;

3. 從權值最小的邊開始,如果這條邊連線的兩個節點於圖g中不在同乙個連通分量中,則新增這條邊到圖g中;

4. 重複3,直至圖g中所有的節點都在同乙個連通分量中。

題目鏈結

部分**講解

//route compression

int findparent(int x)

return root;

}

findparent函式的作用不僅找出x的root節點,而且使x的所有祖先節點的parent都為root,這是並查集的乙個路徑壓縮優化。

void union(int x, int y) 

else }}

union函式的作用就是將兩棵不同的樹按照各自的rank(秩)合併,將秩小的合併到秩大的樹上。

**實現如下:

#include 

#include

#include

#define maxn 100000

using

namespace

std;

struct node

;int parent[maxn], rank[maxn];

void init(int m)

}bool sort_by_price(const node& a, const node& b)

//route compression

int findparent(int x)

return root;

}void union(int x, int y)

else

}}int kruskal(int n, int m, vector

route)

}if (nedge != m-1) return -1;

return res;

}int main()

init(m);

sort(route.begin(), route.end(), sort_by_price);

res = kruskal(n, m, route);

if (res == -1) cout

<< "?"

<< endl;

else

cout

<< res << endl;

}return

0;}

最小生成樹之kruskal演算法

先構造乙個只含 n 個頂點 而邊集為空的子圖,把子圖中各個頂點看成各棵樹上的根結點,之後,從網的邊集 e 中選取一條權值最小的邊,若該條邊的兩個頂點分屬不同的樹,則將其加入子圖,即把兩棵樹合成一棵樹,反之,若該條邊的兩個頂點已落在同一棵樹上,則不可取,而應該取下一條權值最小的邊再試之。依次類推,直到...

最小生成樹之kruskal演算法

克魯斯卡爾 kruskal 演算法過程 構造最小生成樹 u,te 1.置u的初值等於v 即包含有g中的全部頂點 te的初值為空集 即圖t中每乙個頂點都構成乙個連通分量 2.將圖g中的邊按權值從小到大的順序依次選取 若選取的邊未使生成樹t形成迴路,則加入te 否則捨棄,直到te中包含 n 1 條邊為止...

最小生成樹之kruskal演算法

最小生成樹之kruskal演算法 1.kruskal演算法 假設連通網n v,則令最小生成樹的初始狀態為只有n個頂點而無邊的非連通圖t v,圖中每個頂點自成乙個連通分量。在e中選擇最小代價的邊,若該邊依附的頂點落在t中不同的連通分量中,則將該邊加入到t中,否則捨去此邊而選擇下一條代價最小的邊,依次類...