最小生成树

来源:互联网 发布:数据库开发实训基地 编辑:程序博客网 时间:2024/06/05 02:44

数据结构——最小生成树(MST)

什么是最小生成树?

一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。

最小生成树的用途

假设要在 n 个城市之间建立通讯联络网,则连通 n 个城市只需要修建 n-1条线路,如何在最节省经费的前提下建立这个通讯网?

MST 性质

假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v ∈V-U,则最小生成树中必包含边(u,v)。

根据 MST 性质 的两种解法

普利姆算法
克鲁斯卡尔算法

区别

1. 第一步的侧重点不同: 普利姆算法是先保证不构成回路,然后依次求得最小的n-1条边。而克鲁斯卡尔算法则是先排序找到当前最小边,,然后再确保不构成回路,最后集齐N-1条边。至此最小生生成树的伟大任务 完成^_^
2.具体问题选取的时候不同: 普利姆算法 通常用与稠密图,而克鲁斯卡尔算法通常用于稀疏图。

思想

注:点集U 。已经位与生成树T中的点的集合u 。剩余的点U-u

对于普利姆算法:
借助一个数组,这个数组是存取当前剩余的点到生成树中的点最小的权值 例如:closdge[5] ,里面存储的是点4到现有的生成树T的中的最小的边的相关的信息。当然,会用到之前新加入到生成树中的点,以此来求的现有的closedge[].
因此,我们需要设置一个变量K存储新加入的点,借此更新closedge数组。

对于克鲁斯卡尔算法,就要简单的多了(应该掌握,所以,就说的详细点吧)。

这个算法是先保证边权最小,那么显而易见的就要按边权排序啦,(此处可以用qsort 或是sort, 反正都是库里面的,实在不知道,那就冒泡吧)
排过序之后,就要构建生成树啦,。怎么办呢?,这个好办,直接加边呗(注意不要构成回路哦!)。

不构成回路可以采用并查集的思想,,即:元素是否在一个集合中。?这个我们要用程序标识出来,很容易我们可以想到用标识数组,(这一点,我们是站在每个元素的角度上考虑的) 。我们可以用一个数组,用下标表示这个元素,用他里面的值来表示他所在的集合,我们可以用flag[5]=2,flag[7]=2 ,….来表示5和7位与同一个集合2中。

因为如果两个点位与同一个最小生成子树 中的时候,加入这两个点之间的边,就会形成回路。
(最小生成树的一个性质就是如果连接其中的两个点,就会形成回路。当然这个两个点就是位与生成树中的啦,所以我们应该保证我们选取的边所依附的两个点位与不同的点的集合(或是连通子图),这样就不会形成回路了)

这样我们的工作完成的就差不多了,我们只需按照上面的依次找到n-1条边,就OK啦。

具体的代码?大家先思考,以后补上。

0 0