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;
}

216

被折叠的 条评论
为什么被折叠?



