最小生成树

一、Prim

思路:

先选一个节点加入树中,然后不断往这个树增加权值最小的边及其节点,直到形成生成树。

其中,每次找一个节点在这个树内,另一个节点在这个树外的边,在这种边中找权值最小的加入生成树。

最后每个节点都加入树后,形成的是最小生成树。

这里面要用到一个lowcost数组,用来记录从树到这个节点i的最短权值。

#include<bits/stdc++.h>
using namespace std;
const int MAX = 101;
const int MAXCOST = 0x7fffffff;
int graph[MAX][MAX];
//Prim求最小生成树的权值
int Prim(int n){
    int sum = 0;
    int lowcost[MAX];//从树到节点i的最小距离
    int min,minid;
    for(int i = 1;i <= n;i++){
        lowcost[i] = graph[1][i];//初始化lowcost,由节点1到各节点的距离
    }
    lowcost[1] = 0;//节点1加入树
    for(int i = 2;i <= n;i++){//依次寻找其他节点,以最小权值加入树
        min = MAXCOST;
        for(int j = 2;j <= n;j++){
            if(lowcost[j] < min && lowcost[j] != 0){//min记录不在树里的最短边(一个节点在树里,一个节点在树外的边),
                                                    //lowcost不等于0说明这条边不在树里
                min = lowcost[j];
                minid = j;
            }
        }//将合适的节点加入树
        lowcost[minid] = 0;
        sum+=min;//求当前生成树的权值
        for(int j = 2;j <= n;j++){
            if(lowcost[j] > graph[minid][j]){
                lowcost[j] = graph[minid][j];//新节点加入树后,更新树外的节点的距离(看看是否有加入新节点后导致距离缩短的节点)
            }
        }
    }
    return sum;
}
int main(){
    int n,m;
    cout << "input 节点 边数" << endl;
    cin >> n >> m;
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            graph[i][j] = MAXCOST;//初始化图
        }
    }
    int x,y,cost;
    for(int i = 1;i <= m;i++){//读入边
        cin >> x >> y >> cost;
        graph[x][y] = graph[y][x] = cost;
    }
    cost = Prim(n);//传入节点数
    cout << cost << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/gudygudy/p/10526931.html