代码随想录算法训练营Day-56 图论07 | prim算法精讲、kruskal算法精讲

prim算法精讲

prim思路:

1.寻找非生成树节点距离生成树最近的节点

2.将距离生成树最近节点加入生成树

3.更新所有非生成树节点到生成树的最短距离

具体代码细节见代码注释

#include<iostream>
#include<vector>
#include <climits>

using namespace std;
int main(){
    int n,m,s,t,val;
    cin>>n>>m;

    //为什么n+1,因为编号从1,开始共n个,所以需要开辟边长为n+1的邻接矩阵
    //为什么初始化为10001,因为本题val最大值是10000,后面涉及到要比较“连接到cur节点的权值”与“上一状态的到生成树最短距离”,所以把没有连接的节点初始值赋值为一个大值,防止通过if判断
    vector<vector<int>> graph(n+1,vector<int>(n+1,10001));
    while(m--){
        cin>>s>>t>>val;
        //因为是无向图,所以两边都要赋值
        graph[s][t] = val;
        graph[t][s] = val;
    }
    //用来判断节点是否已经加入生成树,初始都不在树中,全为false
    vector<bool> isIntree(n+1,false);
    //用来记录每个节点到生成树的最短距离,因为要记录最小值,所以初始化为最大值
    vector<int> minDist(n+1,INT_MAX);

    //因为连接n个节点只需n-1条边,所以循环n-1次就好了,按照prim算法逻辑,每循环一次就是加一条边
    for(int i=1;i<n;i++){
        
        //----------寻找非生成树节点距离生成树最近的节点----------
        //一开始没有节点在树中,所以先赋值一个cur=1,应对第一次循环的情况
        int cur = 1;
        //用来记录“最近”这个最小值
        int minval = INT_MAX;
        //遍历minDist中的节点,寻找最小值
        for(int j=1;j<=n;j++){
            //节点不能已经在树中,并且当所记录的距离生成树的最短记录小于当前最小值时,就更新最小值,然后把当前节点编号赋值给cur,遍历完minDist数组就找到最小值编号了,也就是非生成树节点距离生成树最近的节点
            if(isIntree[j]==false && minval>minDist[j]){
                minval = minDist[j];
                cur = j;
            }
        }

        //----------将距离生成树最近节点加入生成树----------
        //其实就是把cur位置的isIntree置为true
        isIntree[cur] = true;

        //----------更新minDist数组----------
        for(int k=1;k<=n;k++){
            //因为生成树加入了新的节点,所以可能非生成树节点距离生成树的节点有变化,需要进行更新
            //当节点不在树中,并且与新节点cur连接(不是初始化值10001),且距离小于之前记录的到生成树最短距离,就把最短距离更新为新的距离
            if(isIntree[k]==false && graph[cur][k]<minDist[k]){
                //minDist[k]为之前记录的到生成树最短距离;graph[cur][k]为与新节点cur连接的距离(k节点与cur连接)
                minDist[k] = graph[cur][k];
            }
        }
    }
    int result = 0;
    //此时所有节点都已经加入了生成树(连接在一起),minDist记录了每个节点加入生成树时所使用的距离值,所以只需累加minDist数组即可。由于节点1一开始没有赋距离值就自己加入生成树了,所以节点1的值不计入,从2开始。
    for(int i=2;i<=n;i++) result+=minDist[i];

    cout<<result<<endl;
}

kruskal算法精讲


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值