prim演算法使用模組
阿新 • • 發佈:2018-11-03
prim演算法模組
附帶Kruskal演算法 演算法連結
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
#define MAX 100
#define INF 0x3f3f3f3f
int dist[MAX], path[MAX];
int lowcost[MAX], vst[MAX], v;
struct MGraph
{
int edges[MAX][MAX];//鄰接矩陣,記錄的是兩點之間的距離,也就是權值
int n,e;//頂點數和邊數
}G;
void init() {
memset(G.edges, INF, sizeof(G.edges));//預設為INF
memset(vst, 0, sizeof(vst));
memset(lowcost, INF, sizeof(lowcost));
}
void insert(int u, int v, int w) {
G.edges[u][v] = w;//
}
void Prim(MGraph g,int v0, int &sum){
int i, j, k, min;
v = v0;
for (int i = 0; i < g.n; ++i){
lowcost[i] = g.edges[v0][i];
//cout << lowcost[i] << " ";
vst[i] = 0;
}
vst[v0] = 1; //將v0併入樹
sum = 0; //將sum清零用來累計樹的權值
for(i = 0; i < g.n - 1; ++i) {
min = INF;
//下面這個迴圈用於選出候選邊中的最小值
for(j = 0; j < g.n; ++j) {
if (vst[j] == 0 && lowcost[j] < min){ //選出當前生成樹到其餘頂點最短邊中的最短一條
min = lowcost[j];
k = j;
}
}
vst[k] = 1;
v = k;
//這裡用sum記錄了最小生成樹的權值。如輸出各邊,或者將各邊存入陣列中
sum += min;
//下面這個迴圈以剛併入的頂點v為媒介更新候選邊
for(j = 0; j < g.n; ++j){
if(vst[j] == 0 && g.edges[v][j] < lowcost[j]){ //對應演算法執行過程2
lowcost[j] = g.edges[v][j];
}
}
}
}
int main() {
init();
int n, m;//n個點,m條邊
int x, y, w;
cin >> m >> n;
G.e = m;
G.n = n;
for(int i = 0; i < m; i++){
cin >> x >> y >> w;
insert(x, y, w);
insert(y, x, w);
}
int sum = 0;
Prim(G, 0, sum);
cout << sum << endl;
return 0;
}
/*演算法執行過程 ()
1將vo到其他頂點的所有邊當作候選邊
2重複以下步驟n-1次,使得其他n-1個頂點被併入到生成樹中
從候選邊中挑選出權值最小的邊輸出,
並將與該邊另一端相接的頂點v併入生成樹中
考查所有剩餘的頂點vi,
如果(v,vi)的權值比lowcost[vi]小,
則用(v,vi)的權值更新lowcost[vi]
*/
/*測試資料
8 5
0 1 5
0 2 1
0 3 2
1 2 3
1 4 4
2 3 6
2 4 2
3 4 3
*/