算法导论 第23章 最小生成树 斐波那契堆实现优先队列

最小生成树(Minimum Spanning Tree)问题

    对于一个无向连通图G=(V,E),找出一个无回路的子集T包含于E,连接了所有的顶点,且其权值之和

    

为最小。由于T无回路且连接了所有的顶点,因而必然是一棵树,即生成树,又由于权值和最小,因而叫做最小生成树。确定图G的树T的问题成为最小生成树问题。如下图是图G,阴影边是最小生成树的边,可知权值和为37.

最小生成树一般算法


GENERIC - MST(G)
{
	A <- NULL;
	while A is not a MST
	{
		find an edge(u, v) has the minimum weight is safe for A;
		insert (u,v) to A;
	}
	return A;
}

安全边(safe edge),顾名思义就是在当前剩下的边中具有最小权值,且加入MST后不会形成环的边。具体算法的实现就在于如何筛选安全边。根据筛选安全边的不同,一般有两种最为常用的算法,Kruskal和Prim算法,它们都是贪心算法。


Kruskal算法

    kruskal算法时贪心策略的运用。将所有边按照权值从小到大排序,然后顺序扫描这些边,只要是安全的即将边加入MST中。判断是否安全的准则是边两端点是否有同一个祖先,采用不相交数据集合可以很快查得。下面是其算法代码:

MST-KRUSKAL(G)
{
	A <- NULL;
	for each vertex v in V[G]
		MAKE-SET(V);
	sort all edges of E into nondecreasing order by weight;
	for every edge(u,v) in E,taken in nondecreasing order by weight
		if FIND-SET(u) != FIND-SET(v)
		{
			insert (u, v) to A;
			UNION(u, v);
		}
	return A;
}


时间复杂度O(ElgE),由于是连通图,故|V| - 1 <= E <= |V|^2,所以lgE = O(lgV),故时间也可表述为O(ElgV)。具体实现代码如下,后面将会给出用到的所有代码,相关约定请参看图的基本算法(一)

size_t AGraph::kruskal(AGraph *mst)
{//克鲁斯卡尔算法求最小生成树,返回最小权值和,最小生成树记录在mst中
	struct findRoot:public binary_function<vector<size_t>,size_t,size_t>
	{//局部函数对象类,用于查询并查集
		size_t operator()(const vector<size_t> &UFS, size_t v)const
		{
			while (v != UFS[v]) v = UFS[v];
			return v;
		}
	};
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值