普里姆算法(最小生成树)


/*请把这个例子和Dijkstra算法一起看,会发现他们几乎一模一样有木有!*/
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define inf 65535
void prim(int c[][7],int n,int lowcost[],int closest[])//c是邻接矩阵,n为顶点个数,i从2到6,因为prim算法的初始顶点是任意的,索性就取顶点1作为初始顶点
{													   //lowcost[i]代表一轮V-S中的顶点i到S的所有点中最小的距离值,closest[i]表示每一轮每个顶点i到集合S中对应距离的最小值的那个顶点,即边i-closest[i]是针对i来说到集合S所有点的距离中最小的那个边 
	int s[7];//s判断顶点是否在S中,如果在就是1,不在就是0 
	for(int i=2;i<=n;i++)//初始化,除1之外的所有的点的lowcost[]都是直接与顶点1的距离 
	{
		lowcost[i]=c[1][i];
		closest[i]=1;//同时,closest[]初始化为1,毕竟此时S中只剩1号一个 
		s[i]=0;//现在顶点2到顶点6均未加入S阵营 
	}
	s[1]=1;//S中现在只剩1号一个 
	for(int i=1;i<=n-1;i++)//开始迭代,迭代次数为n-1 
	{
		int min=inf,j;//min和j用于记录每轮各个顶点(i从2到6)lowcost[i]的最小值,j用于记录顶点号 
		for(int k=2;k<=n;k++)//开始寻找最小值和最小值对应的顶点号了,这就是简单的擂台赛 
			if(!s[k]&&lowcost[k]<min)
			{
				min=lowcost[k];
				j=k;
			}
		s[j]=1;//此时lowcost[i]的最小值对应的顶点号是j,那么就要把顶点j加入S集合中 
		for(int k=2;k<=n;k++)//顶点j加入了,此时需要修改现在的V-S阵营中每个顶点的lowcost[]和closest[]值,因为S发生了变化,因此相应的就需要改变 
			if(!s[k]&&c[j][k]<lowcost[k])//如果发现还有更小的,就更新lowcost[]和closest[]值,注意两个都要更新,不能只更新一个! 
			{
				lowcost[k]=c[j][k];
				closest[k]=j;
			}
	}
} 
void print(int lowcost[],int closest[],int n)//打印结果 
{
	for(int i=2;i<=n;i++)
		cout<<i<<"--"<<closest[i]<<":"<<lowcost[i]<<endl;
}

int main()
{
	int c[7][7]={  //因为我的顶点号是从1开始的,一共6个顶点,所以我申请了一个7×7的矩阵,下标为0的地方我设置成无穷大,不影响最后结果 
				{inf,inf,inf,inf,inf,inf,inf},
				{inf,inf,6,1,5,inf,inf},
				{inf,6,inf,5,inf,3,inf},
				{inf,1,5,inf,5,6,4},
				{inf,5,inf,5,inf,inf,2},
				{inf,inf,3,6,inf,inf,6},
				{inf,inf,inf,4,2,6,inf},
				};
	int lowcost[7],closest[7];
	prim(c,6,lowcost,closest);
	print(lowcost,closest,6);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值