最小生成樹 kruskal

2021-09-27 13:32:43 字數 1579 閱讀 3714

將乙個連通圖的邊全部刪除,剩下乙個個頂點。通過選擇最短路徑連線對應的頂點,直至構成一棵生成樹,則這棵生成樹一定是最小生成樹。kruskal演算法就是通過此方法來建立一棵最小生成樹的。其通過不斷新增邊的過程構成最小生成樹。區別於kruskal演算法,prim演算法則是通過新增點來構造最小生成樹。

構造過程:

儲存各頂點間邊的連通情況及其對應權值,按對應權值排序(選擇最短路徑/最小權值連線對應頂點)

將連通圖劃分成乙個個單一頂點(刪除全部邊)

選擇最短路徑(最小權值),將邊新增到相應的兩個頂點間

生成樹中是沒有迴路的,則重構過程如何避免迴路?分析發現,如果選中邊的對應頂點的連通域相同,則一定會產生迴路,因此這樣的兩個頂點不能連線

直至所有頂點在同乙個連通域中,否則重複步驟3

關於步驟四的分析:

如上圖,因為邊權值1、2、3、4最小,所以優先連線相應的邊。當權值取5時,發現頂點1和4可以連線,頂點3和4可以連線,頂點2和3也可以連線。倘若連線頂點1和4,則頂點3、4、6構成迴路(不是生成樹)。這時候我們則可以通過連通域來判斷選擇哪條邊。當頂點1和3連線時構成連通域1,頂點4和6連線時構成連通域4,頂點3和6連線,此時連通域不同(乙個是1,乙個是4。1,4可以隨便選擇,這裡只是為了區別不同的連通域)因此可以連線,連線後構成了乙個大的連通域,我們不妨稱其為連通域1。倘若選擇頂點3和4連線,但它們屬於同一連通域,則會產生迴路,因此選擇下一條邊。當選擇頂點1和4時,同樣屬於乙個連通域也不能選擇,則再選擇下一條邊。即連通域相同的兩個頂點不能相互連線。

演算法步驟:

如構造過程步驟1,需要儲存連通圖中邊的關係(起始頂點,終止頂點,權值),因此我們宣告乙個結構體儲存

單一頂點(每乙個頂點即乙個連通域,連通域內僅自己)可以用一維陣列儲存,表示頂點所屬的連通域

按連通圖中邊的權重大小排序(公升序)

選擇權值最小的邊,檢視其相應的頂點所屬連通域是否相同,如果相同則不能連線(產生迴路),否則連線相應的邊(記錄相應的權值)

直至所有頂點在同乙個連通域中,否則重複步驟4

**示例:

#include

#include

using

namespace std;

#define max_size 100

struct edge

;int con[max_size]

;edge edge[max_size]

;bool

cmp(edge x, edge y)

void

init_graph

(int m)

}int

kruskal

(int n,

int m)

for(

int i =

0; i < m; i++)}

}}return sum;

}int

main()

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 這條邊連線...