概述
最小生成树算法Prime
最小生成树(MST):权值最小的生成树。
生成树和最小生成树的应用:要连通n个城市需要n-1条边线路。可以把边上的权值解释为线路的造价。则最小生成树表示使其造价最小的生成树
注意:prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。
算法思路:
G=(V, E),首先置S={1},只要S是V的真子集,就进行如下的贪心选择,选取满足条件i属于S,j属于V-S,且
matrix[i][j]是最小的边,将j加入到S中,这个过程一直持续到S=V为止,在这个过程中选择的所有边恰好构
成G的一棵最小生成树。
#include <stdio.h>
#include <string.h>
#define MaxInt 0x3f3f3f3f
#define N 110
//创建map二维数组储存图表,low数组记录每2个点间最小权值,visited数组标记某点是否已访问
int map[N][N],low[N],visited[N];
int n;
int prim()
{
int i,j,pos,min,result=0;
memset(visited,0,sizeof(visited));
//从某点开始,分别标记和记录该点
visited[1]=1;pos=1;
//第一次给low数组赋值
for(i=1;i<=n;i++)
if(i!=pos) low[i]=map[pos][i];
//再运行n-1次
for(i=1;i<n;i++)
{
//找出最小权值并记录位置
min=MaxInt;
for(j=1;j<=n;j++)
if(visited[j]==0&&min>low[j])
{
min=low[j];pos=j;
}
//最小权值累加
result+=min;
//标记该点
visited[pos]=1;
//更新权值
for(j=1;j<=n;j++)
if(visited[j]==0&&low[j]>map[pos][j])
low[j]=map[pos][j];
}
return result;
}
int main()
{
int i,v,j,ans;
while(scanf("%d",&n)!=EOF)
{
//所有权值初始化为最大
memset(map,MaxInt,sizeof(map));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
scanf("%d",&v);
map[i][j]=map[i][j]=v;
}
ans=prim();
printf("%dn",ans);
}
return 0;
}
最后
以上就是虚心大树为你收集整理的Prim 算法的全部内容,希望文章能够帮你解决Prim 算法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复