日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(最小生成树)prim算法

發(fā)布時間:2025/3/12 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (最小生成树)prim算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

總結(jié)一下:

如果選 0為起點,low_cost[i]表示以 0這個起點到i 這個終點的權(quán)值,我們找最小的權(quán)值的終點i,然后以i為起點,去更新low_cost[]這個數(shù)組,如果與i相連的數(shù)是j,現(xiàn)在有兩種情況,j與0相連,j與i相連但不與0相連。如果j也與0相連,我們找0到j(luò)和i到j(luò)這兩者的最小距離,然后用這個最小的距離更新low_cost[j]。如果j不與0相連,那么就直接填上low_cost[j]

代碼分析一下:

matrix[i][j]=m意思是以i為起點j為終點的權(quán)值為m
path[i]=a,意思是i起點連的是a終點
由此我們可見數(shù)組可以表達(dá)的意思可以是那幾個變量之間的相關(guān)性

visit數(shù)組存的是目前最小生成樹上已經(jīng)有的結(jié)點,我們最小生成樹最終是要有所有的結(jié)點的

先找一個起點,然后把與起點相連的路徑都存到low_cost里

找一個終點,起點到他的權(quán)值最小,將這個終點進(jìn)行標(biāo)記(證明已經(jīng)將其加入到最小生成樹里面了),并且記錄最小路徑和的sum要加上他的權(quán)值

由于low_cost目前只存了與起點相連的路徑,現(xiàn)在最小生成樹里面加入了一個新的結(jié)點,那么我們就需要更新low_cost數(shù)組,把與這個新的結(jié)點相連的路徑加入到low_cost數(shù)組里,路徑就要考慮終點,這個終點一定不是在最小生成樹里的,所以要用到visit數(shù)組,然后如果matrix[min_cost_index][j]就是這個新節(jié)點到某一終點的權(quán)值比low_cost[j]小的話,就更新low_cost[j]

#include <iostream>using namespace std;int matrix[100][100]; // 鄰接矩陣 bool visited[100]; // 標(biāo)記數(shù)組 int low_cost[100]; // 邊的權(quán)值 int path[100]; // 記錄生成樹的路徑 int source; // 指定生成樹的起點 int vertex_num; // 頂點數(shù) int edge_num; // 邊數(shù) int sum; // 生成樹權(quán)和void Prim(int source) {memset(visited, 0, sizeof(visited));visited[source] = true;for (int i = 0; i < vertex_num; i++){low_cost[i] = matrix[source][i];path[i] = source;}int min_cost; // 權(quán)值最小int min_cost_index; // 權(quán)值最小的下標(biāo)sum = 0;for (int i = 1; i < vertex_num; i++) // 除去起點,還需要找到另外 vertex_num-1 個點{min_cost = INT_MAX;for (int j = 0; j < vertex_num; j++){if (visited[j] == false && low_cost[j] < min_cost) // 找到權(quán)值最小{min_cost = low_cost[j];min_cost_index = j;}}visited[min_cost_index] = true; // 該點已找到,進(jìn)行標(biāo)記sum += low_cost[min_cost_index]; // 更新生成樹權(quán)和for (int j = 0; j < vertex_num; j++) // 從找到的最小下標(biāo)更新 low_cost 數(shù)組{if (visited[j] == false && matrix[min_cost_index][j] < low_cost[j]){low_cost[j] = matrix[min_cost_index][j];path[j] = min_cost_index;}}} }int main() {cout << "請輸入圖的頂點數(shù)(<=100):";cin >> vertex_num;cout << "請輸入圖的邊數(shù):";cin >> edge_num;for (int i = 0; i < vertex_num; i++)for (int j = 0; j < vertex_num; j++)matrix[i][j] = INT_MAX; // 初始化 matrix 數(shù)組cout << "請輸入邊的信息:\n";int u, v, w;for (int i = 0; i < edge_num; i++){cin >> u >> v >> w;matrix[u][v] = matrix[v][u] = w;}cout << "請輸入起點(<" << vertex_num << "):";cin >> source;Prim(source);cout << "最小生成樹權(quán)和為:" << sum << endl;cout << "最小生成樹路徑為:\n";for (int i = 0; i < vertex_num; i++)if (i != source)cout << i << "----" << path[i] << endl;return 0; } /* 請輸入圖的頂點數(shù)(<=100):5 請輸入圖的邊數(shù):7 請輸入邊的信息: 0 1 8 0 2 3 0 3 2 1 3 3 3 2 4 2 4 1 3 4 5 請輸入起點(<5):0 最小生成樹權(quán)和為:9 最小生成樹路徑為: 1----3 2----0 3----0 4----2 */

不過上面這個適合理解不適合去作為模板
因為往往下標(biāo)從一開始
這有一個模板

#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define N 150 #define INF 99999999 int ma[N][N]; long long d[N],vis[N]; int n; long long prim(int s) {memset(vis,0,sizeof(vis));for(int i=1; i<=n; i++)d[i]=i==s?0:ma[s][i];vis[s]=1;long long ans=0;for(int i=1; i<n; i++){int maxn=INF,v;for(int j=1; j<=n; j++)if(!vis[j]&&maxn>d[j]){maxn=d[j];v=j;}vis[v]=1;ans+=maxn;for(int j=1; j<=n; j++)if(!vis[j]&&ma[v][j]<d[j])d[j]=ma[v][j];}return ans; }main那里面 先輸入數(shù)組ma 然后 long long ans=prim(1);printf("%lld\n",ans);

總結(jié)

以上是生活随笔為你收集整理的(最小生成树)prim算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。