最小生成樹之prime演算法(鄰接矩陣實現)

2021-09-22 23:15:09 字數 3430 閱讀 4297

【概念】:

***生成樹:乙個連通圖的生成樹,指的是該圖的乙個子圖(沒有形成迴路),他包含圖的所有結點,但只有把所有結點連線在一起的n-1條必要的邊;

***最小生成樹:乙個連通圖的生成樹中,所有邊的權值加起來最小的生成樹;稱為最小生成樹;

【簡介】:prime演算法可在加權連通圖里搜尋最小生成樹。即:所有邊的權值之和為最小。

prime演算法是圖論中求最小生成樹的一種演算法,與之類似的演算法還有kruskal演算法;

區別:prime演算法適合邊多定點少的圖;

2.dijkstra演算法適合邊少定點多的圖;

要求最小生成樹,當然首先要把圖存進乙個東西中,這樣才能圖對進行搜尋操作。

一般的存圖方式有三種:

1.鄰接矩陣

存圖思想:用乙個矩陣來記錄乙個圖,矩陣第 i 行第 j 列的值就表示頂點 i 到頂點 j 的權值

1.2 鄰接表

存圖思想:對每個頂點,使用不定長的鍊錶來儲存從該點出發的所有邊的情況,第 i 個鍊錶的第 j 個值就是頂點 i 到頂點 j 的權值。

1.3 鏈式前向星

存圖思想:主要的資料結構是邊陣列(儲存邊的陣列),當然想要完美表示圖,光有乙個邊集陣列還不夠,還要有乙個陣列每乙個點的第一條邊。同時,每一條邊都需要儲存接下來一條邊的「指標」

1.2.1 用到的陣列

我寫的這個prime演算法存圖用的是鄰接矩陣。

int mp[n][n]; //使用鄰接矩陣存圖;

int dis[n]; //到生成樹的最短距離;

int vis[n]; //標記陣列,標記該結點是否納入集合,即該結點是否訪問過;

int p[n]; //儲存父親結點;

1.2.2 初始化

初始化:自己與自己的距離為0,自己與別的結點的距離初始化為無窮大,即,表示不連通;

將所有的結點都標記為為訪問,我這用0表示未訪問,1表示已訪問;

memset(vis, 0, sizeof(vis)); //全部未訪問過

無窮大:#define inf 0x3f3f3f3f

void inin(int n)//初始化:mp陣列初始化,vis標記陣列初始化;

}}

1.2.3 prime演算法主體

傳入乙個節點,當然,傳入的這個節點是隨意的。將這個點到其他點的距離存入dis陣列,並將傳入的這個點標記為已訪問。

然後找出從st(傳入的那個點)出發的路徑中的最短的乙個路徑;並將它到達的那個點記性並標記。然後更新dis陣列(重點):如果該結點沒有被訪問過,且點距離當前點的距離更近,就執行更新;最後dis陣列中就是最小生成樹的最短路徑的集合;對其求和,即是最小生成樹的最短路徑;

**實現:

void

prime

(int st,

int n)

//st是任意乙個開始的結點,此節點隨意;

dis[i]

= mp[st]

[i];

} vis[st]=1

;//將該點標記為訪問過;

while(1

)}if(k ==-1

)//所有結點都已訪問;即:已生成最小生成樹;跳出死迴圈;

vis[k]=1

;//將剛才i連線的結點標記為已訪問;

for(i =

1; i <= n; i++

)//更dis陣列,}}

for(i =

1; i <= n; i++

)}

完整的使用鄰接矩陣存圖的prime演算法如下:

#include

#include

using namespace std;

#define n 1000

#define inf 0x3f3f3f3f

int mp[n]

[n];

//使用鄰接矩陣存圖;

int dis[n]

;//到生成樹的最短距離;

int vis[n]

;//標記陣列,標記該結點是否納入集合,即該結點是否訪問過;

int sum =0;

int p[n]

;//父親結點;

void

inin

(int n)

//初始化:mp陣列初始化,vis標記陣列初始化;}}

void

prime

(int st,

int n)

//st是任意乙個開始的結點,此節點隨意;將st看做最小生成樹的根節點

dis[i]

= mp[st]

[i];

} vis[st]=1

;//將該點標記為訪問過;

while(1

)}if(k ==-1

)//所有結點都已訪問;即:已生成最小生成樹;跳出死迴圈;

vis[k]=1

;//將剛才i連線的結點標記為已訪問;

for(i =

1; i <= n; i++

)//更dis陣列,}}

for(i =

1; i <= n; i++)}

void

parent

(int n)

}int

main()

}prime(1

, n)

; cout << sum << endl;

parent

(n);

return0;

}

輸入樣例:

如果傳入的結點是1,那麼,

剛開始的dis陣列如下:

0 0 4 9 21

執行更新之後:

0 0 4 8 16

當然,你也可以在輸入的時候指定特定點之間的距離:

例:x到y的距離為sp;

x y sp

1 2 5

1 3 3

1 4 7

1 5 4

1 6 2

inin

(n);

for(

int i=

1;i<=m;i++

)prim()

;parent()

;

Prime演算法求最小生成樹 鄰接表)

name prime演算法求最小生成樹 鄰接表 author 巧若拙 date 25 11 14 13 38 description 實現了 prime演算法求最小生成樹 鄰接表 的普通演算法和最小堆優化演算法。include include define max 2000 最大頂點數量 defin...

最小生成樹之prime演算法

在這裡我就不擺最小生成樹的定義了,對於最小生成樹,我們必須注意一下兩點 1 盡可能選取權值小的邊,但不能構成迴路。2 選取合適的n 1條邊將聯通圖的n個頂點連線起來。演算法簡單描述 1 輸入 乙個帶權連通圖,其中頂點集合為v,邊集合為e 2 初始化 vnew 其中x為集合v中的任一節點 起始點 en...

最小生成樹 Prime演算法

對於乙個圖,它的所有生成樹中必有乙個 邊的權值最小 的生成樹,我們把它稱為最小生成樹。概念很抽象,換做實際問題 有十個城市,各個城市之間距離或遠或近。需要建設乙個道路網,把十個城市連線在一起,要求道路網的道路長度最小。各個城市的連線可以抽象為乙個圖,本質上即是求該圖的乙個最小生成樹。每乙個圖可能有多...