Prim和Kruskal算法实现最小生成树

最小生成树的两种算法

1.问题描述
在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树
2.Prim算法
Prim算法即加点法 将一个起始点加入集合V中,寻找与集合相连并且距离最近的点加入集合,要求不可形成回路,否则舍弃此边继续寻找,重复此过程,直至所有点均加入集合

起始点 V0
在这里插入图片描述加入V2

在这里插入图片描述
加入离集合最近的V4
在这里插入图片描述加入V1
在这里插入图片描述
最后加入V3,所有点均加入集合,结束运算
在这里插入图片描述使用parent数组记录各个点的父节点信息,当所有点均记录后这个数组就记录了最小生成树

void Prim(int point)
{
	parent[point]=-1;
	while(end<n)                                  //while循环当加一个点时end+1 
	{
		int i,j;
		for(i=0;i<n;i++)
		{

			if(parent[i]!=-2)                              //当起点被访问时进行下步操作 
			{
				for(j=0;j<n;j++)
				{
					if(map[i][j]<=min&&map[i][j]>0&&parent[j]==-2)                 //记录最短且终点未被访问的边的信息 
					{ 
						min1=i;
						min2=j;
						min=map[i][j];
					}
				}	
			}
		}			
			parent[min2]=min1;                                          //加入最小生成树 
			end++;
			min=1e5;
	}
} 

3.Kruskal算法
Kruskal算法即加边法 将边从小到大排序,从最小的边开始访问,在不形成闭环的情况下,将边先生成森林,再将森林连成一棵树

int  kruskal()
{
	int i;
	for(i=0;i<pn;i++)
	{
		v[i]=i;
	}
	int num=pn;
	for(i=0;i<en&&num>1;i++)
	{
		int p1=getroot(m[i].point1);
		int p2=getroot(m[i].point2);
		if(p1!=p2)
		{
			v[p1]=p2;
			num--;
		}
	}
	for(i=0;i<en;i++)
	{
		if(v[m[i].point1]!=m[i].point1)
		printf("%d-%d\n",m[i].point1,m[i].point2);
	}
}

4.源码
github:
https://github.com/1651928813/Pepsi_juice

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值