prim算法使用模块

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

猜你喜欢

转载自blog.csdn.net/qq_42866708/article/details/81734798