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
*/