最小生成树之Prim算法分析

最小生成树问题

设G=(V,E)是无向连通带权图,即一个网络。图中每一条边(u,v)的权是c[u][v],表示联通u与v的代价。
如果G的子图T是一棵包含G的所有顶点的树,则称T为G的生成树。生成树上各边权的总和称为该生成树的耗费。在G的所有生成树中,耗费最小的生成树称为G的最小生成树:

最小生成树之Prim算法分析_第1张图片

算法思想

贪心算法可以设计出构造最小生成树的有效算法。
PrimKruskal算法都是应用贪心算法设计的。

Prim算法基本思想

设G=(V,E)是连通带权图,V={v1,v2,…,vn}
首先置S={vx},这里vx为任意起点(vx∈V),然后重复执行下列操作:

  • 只要S是V的真子集,就作出如下贪心选择
  • 选取满足条件vi∈S,vj∈V-S,且c[i][j]是权值最小的边,则将顶点vj添加到S中。
  • 这个过程一直进行到S=V时为止(即S中边数为n时),此时选取到的所有边恰好构成G的一颗最小生成树。

下面绘图的形式来演示Prim算法的具体过程,这里选取v1为起点,具体算法中根据Prim函数的start来决定起点。
最小生成树之Prim算法分析_第2张图片

核心伪代码

int Prim(i int start)// start为起始顶点 
{
	int lowcost[MAX];//最小权值
	int closest[MAX];//前缀顶点
	bool S[MAX];//集合S 
	for (初始化所有顶点)
	{
		lowcost[i] = cost[start][i];//其余顶点与顶点start的最小距离
		closest[i] = start;
		S[i] = false;//初始化集合S为空 
	}
	S[start] = true;//顶点start加入集合S
	for (遍历除start外剩余顶点) 
	{
	找到不在集合S中的最小边权的顶点j
	}
		sumweight += lowcost[j];//加上权重
		S[j] = true;//顶点j加入S集合
		for (遍历所有点) 
			if ((!S[k]) && (cost[j][k] < lowcost[k])) //若有更小的权重
			{
			/更新lowcost和closest
			}
	return sumweight;//返回权重和
}

算法复杂度分析


Prim算法的时间复杂度与网中的边数无关,适合于稠密图,时间复杂度O(n²),但可以用堆优化,优化后的Prim算法时间复杂度O(mlogn)。

你可能感兴趣的:(最小生成树之Prim算法分析)