第8章第2節 再談最小生成樹 Prim演算法

2021-09-18 06:19:41 字數 1299 閱讀 5372

/*

prim的時間複雜度為o(n2)

演算法流程:

1.從任意乙個頂點開始構造生成樹,假設就從1號頂點吧,首先將頂點1加入生成樹中,用乙個一維陣列book

來標記哪些頂點已經加入了生成樹。

2.用陣列dis記錄生成樹到各個頂點的距離。最初生成樹只有1號頂點,有直連邊時,陣列dis中儲存的就是1號頂點到改頂點的

邊的權值,沒有直連邊時就是無窮大,即初始化dis陣列。

3.從陣列dis中選擇出離生成樹最近的頂點(假設這個頂點為j)加入到生成樹種(即在陣列dis中找最小值)即如果dis[k]>e[j][k]

則更新dis[k]=e[j][k]

4.重複第3步,直到生成樹中有n個頂點為止

*/#include "stdio.h"

int main()

;//這裡對book陣列進行了初始化

int inf = 99999999;//用inf(infinity的縮寫)儲存乙個我們認識的無窮大

int count = 0,sum = 0;//count用來記錄生成樹中頂點的個數,sum用來儲存路徑之和

//讀入n和m,n表示頂點個數,m表示邊的條數

scanf("%d %d",&n,&m);

//初始化

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

else}}

//開始讀入邊

for(i = 1;i <= m;i++)

//初始化dis陣列,這裡是1號頂點到各個頂點的初始距離,因為當前生成樹只有1號頂點

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

//prim核心部分開始

//將1號頂點加入生成樹

book[1] = 1;//這裡用book來標記乙個頂點是否已經加入生成樹

count++;

while(count < n)

}book[j] = 1;

count++;

sum = sum + dis[j];

//掃瞄當前j所有的邊,再以j為中間點,更新生成樹到每乙個非樹頂點的距離

for(k = 1;k <= n;k++)}}

printf("%d\n",sum );//列印結果

getchar();getchar();

return 0;}/*

示例輸入:

6 92 4 11

3 5 13

4 6 3

5 6 4

2 3 6

4 5 7

1 2 1

3 4 9

1 3 2

示例輸出:

19*/

演算法導論 第23章 最小生成樹

最小生成樹 minimum spanning tree 全稱 最小權值生成樹 在含有n個頂點的連通圖中選擇n 1條邊,構成一棵極小連通子圖,並使該連通子圖中n 1條邊上權值之和達到最小,則稱其為連通網的最小生成樹。有兩種具體的實現演算法 kruskal演算法 prim演算法 兩者都用到了貪心演算法。...

最小生成樹(演算法導論第23章)

下面討論的兩種最小生成樹演算法都是貪心演算法。貪心演算法的每一步必須在多個可能的選擇中選擇一種,貪心演算法選擇在當前看來最好的選擇。通用演算法是每個時刻生長最小生成樹的一條邊 安全邊 並在整個策略的實施過程中,管理乙個遵守下述迴圈不變式的邊集合a 在每遍迴圈之前,a是某棵最小生成樹的子集。gener...

《演算法導論》第23章 最小生成樹

在上圖中,就是邊cd。這兩個定理看不懂沒關係,不影響後面學習kruskal演算法與prim演算法。kruskal演算法 我的理解 1 尋找權值最小的邊,如果邊的兩個頂點屬於不同的集合就加入到a 2 重複過程1,直到找到n 1條邊 第一點中分集合的方法我借鑑了wxdjss的部落格,以下是他的部落格鏈結...