#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int MAX = 0x3f3f3f,INF = 0x3f3f3f3f;//MAX定义邻接矩阵的边界;INF定义一个无穷大的值,方便下面进行比较。
int n,g[MAX][MAX],d[MAX];/*n代表网中点的个数,d[i]代表点i到当前树【可能只有一部分树】的距离:g[i][j]代表i到j的距离,即邻接
矩阵中i行j列中的数值。*/
bool vst[MAX]={false};//判断一个点是否已被搜索过。
int ans = 0;//计算构造生成树所需要的代价,即权值之和。
void prime(int x){//x表示从编号为x的点出发,按路径寻找最小生成树。
memset(d,INF,sizeof(d));//先假设所有的点到当前树的距离均为无穷大,方便下面程序的执行。
d[x] = 0;//表示点x到点x的距离为0。
for(int i = 0;i < n;i++){
int u = -1,MIN = INF;
for(int j = 0;j < n;j++){
if(vst[j]==false && d[j] < MIN){//找出与点x邻接的权值最小的点:u进行位置储存,MIN进行权值储存。
u = j; /*如果没有找到,即当前搜索的点和当前树无法直接相连,那么if()循环便不
会被执行,u和MIN不会被改变。两者组合起来仍表示点和树之间无法直接相连。*/
MIN = d[j];
}
}
vst[u] = true;//标记已经当前已搜索的点。
ans += MIN;//生成代价加和。
for(int v = 0;v < n;v++){
if(vst[v]==false && g[u][v] != INF && g[u][v] < d[v]){
d[v] = g[u][v];//在建立出一个新的生成树树枝后,判断是否需要进行数值更新。
}
}
}
}
int main(){
ios::sync_with_stdio(0);
while(cin>>n){//输入一共有多少个点,n=点的个数-1.
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>g[i][j];
}
}//输入邻接矩阵中具体的值。
prime(0);//以编号为0的点为起点,进行搜索。
cout<<ans<<endl;//输出最小代价。
ans=0;
memset(vst,false,sizeof(vst));//对数值进行初始化,便于下次进行。
}
return 0;
}
prim算法小笔记
猜你喜欢
转载自blog.csdn.net/StarrYooSkY/article/details/79224061
今日推荐
周排行