最小生成树—(Kruskal算法 )

Kruskal 算法

Kruskal算法的第一步是给所有边按照从大到小的顺序排列。这一步可以直接使用库函数qsort或者sort.接下来从小到大一次考察每个边(u,v)。

情况1:u和v在同一个连通分量中,那么加入(u,v)后会形成环,因此不能选择。
情况2:如果u和v在不同的连通分量,那么加入(u,v)一定是最优的。
原因可用反证法证明——如果不加这条边能到得到一个最优解T,则T+(u+v)一定有且只有一个环,而且环中至少又一条边(u’,v’)的权值>或=(u,v)的权值。删除该边后,得到的新树T’=T+(u,v)-(u’,v’)不会比T更差。
因此,加入(u,v)不会比不加差

语言描述的伪代码:
<向下的箭头>

把所有边排序,记第i小的边为e[i](1<=i<=m)    //m条边
初始化MST为空
初始化连通分量,让每个点自成一个独立的连通分量
for(int i=0;i<m;i++)
	if(e[i].u和e[i].v不在同一个连通分量){
		把边e[i]加入MST
		合并e[i].u和e[i].v所在的连通分量
	}

在上面的伪代码中,最关键的地方在于“连通分量的查询与合并”:需要知道任意两个点是否在同一个连通分量,还需要合并两个连通分量。(特别像并查集,就是)
这里有一种简洁高效的方法用来处理这个问题就是依靠并查集

关于并查集可以看另一篇博客。

猜你喜欢

转载自blog.csdn.net/weixin_43916296/article/details/86618542