/*
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的部落格,以下是他的部落格鏈結...