转 最小生成树(kruskal 算法 和prim算法)

链接:http://blog.csdn.net/weinierbian/article/details/8059129/

给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树.

求最小生成树的算法
(1) 克鲁斯卡尔算法
图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是任意的.该方法对于边相对比较多的不是很实用,浪费时间.
(2) 普里姆算法
图的存贮结构采用邻接矩阵.此方法是按各个顶点连通的步骤进行,需要用一个顶点集合,开始为空集,以后将以连通的顶点陆续加入到集合中,全部顶点加入集合后就得到所需的最小生成树 .



下面来具体讲下:
克鲁斯卡尔算法
方法:将图中边按其权值由小到大的次序顺序选取,若选边后不形成回路,则保留作为一条边,若形成回路则除去.依次选够(n-1)条边,即得最小生成树.(n为顶点数)

第一步:由边集数组选第一条边

第二步:选第二条边,即权值为2的边

第三步:选第三条边,即权值为3的边

第四步:选第四条边,即权值为4的边

第五步:选第五条边



普里姆算法
方法:从指定顶点开始将它加入集合中,然后将集合内的顶点与集合外的顶点所构成的所有边中选取权值最小的一条边作为生成树的边,并将集合外的那个顶点加入到集合中,表示该顶点已连通.再用集合内的顶点与集合外的顶点构成的边中找最小的边,并将相应的顶点加入集合中,如此下去直到全部顶点都加入到集合中,即得最小生成树.
例在下图中从1点出发求出此图的最小生成树,并按生成树的边的顺序将顶点与权值填入表中.

———————>先写出其邻接矩阵

第一步:从①开始,①进集合,用与集合外所有顶点能构成的边中找最小权值的一条边
①——②权6
①——③权1 -> 取①——③边
①——④权5

第二步:③进集合,①,③与②,④,⑤,⑥构成的最小边为
①——④权5
③——⑥权4 -> 取③——⑥边

第三步:⑥进集合,①,③,⑥与②,④,⑤构成的各最小边
①——②权6
③——②权5
⑥——④权2 -> 取⑥——④边

第四步:④进集合,①,③,⑥,④与②,⑤构成的各最小边
①——②权6
③——②权5 -> 取③——②边
⑥——⑤权6

第四步:②进集合,①,③,⑥,②,④与⑤构成的各最小边
②——⑤权3 -> 取②——⑤边



这也是在网上找到的一个Kruskal和Prim构造过程图,贴出来:

时间: 2024-10-05 04:24:38

转 最小生成树(kruskal 算法 和prim算法)的相关文章

贪心算法-最小生成树Kruskal算法和Prim算法

Kruskal算法: 不断地选择未被选中的边中权重最轻且不会形成环的一条. 简单的理解: 不停地循环,每一次都寻找两个顶点,这两个顶点不在同一个真子集里,且边上的权值最小. 把找到的这两个顶点联合起来. 初始时,每个顶点各自属于自己的子集合,共n个子集合. 每一步操作,都会将两个子集合融合成一个,进而减少一个子集合. 结束时,所有的顶点都在同一个子集合里,这个子集合就是最小生成树. 例子: 伪代码: Prim算法: G=(V,E),S是V的真子集,如果u在S中,v在V-S中,且(u,v)是图的一

最小生成树之Kruskal算法和Prim算法

依据图的深度优先遍历和广度优先遍历,能够用最少的边连接全部的顶点,并且不会形成回路. 这样的连接全部顶点并且路径唯一的树型结构称为生成树或扩展树.实际中.希望产生的生成树的全部边的权值和最小,称之为最小生成树. 常见的最小生成树算法有Kruskal算法和Prim算法. Kruskal算法每次选取权值最小的边.然后检查是否增加后形成回路,假设形成回路则须要放弃.终于构成最小生成树.n个顶点的图最小生成树过程例如以下: 边的权值升序排序. 选取全部未遍历的边中权值最小的边,推断增加后是否形成回路,若

hdu 1162 Eddy's picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法.保证联通的线路最短,典型的最小生成树问题. 方法一 . 通过不断找到最小的边来找到终于结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac

hdu 1162 Eddy&#39;s picture (Kruskal算法,prim算法,最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 [题目大意] 给你n个点的坐标,让你找到联通n个点的一种方法,保证联通的线路最短,典型的最小生成树问题. 方法一 , 通过不断找到最小的边来找到最终结果. Kruskal 算法 #include <iostream> #include <algorithm> #include <cstdio> #include <cmath> using namespac

Algorithm --&gt; Kruskal算法和Prim算法

最小生成树之Kruskal算法和Prim算法 根据图的深度优先遍历和广度优先遍历,可以用最少的边连接所有的顶点,而且不会形成回路.这种连接所有顶点并且路径唯一的树型结构称为生成树或扩展树.实际中,希望产生的生成树的所有边的权值和最小,称之为最小生成树.常见的最小生成树算法有Kruskal算法和Prim算法. Kruskal算法 每次选取权值最小的边.然后检查是否加入后形成回路,如果形成回路则需要放弃.最终构成最小生成树.n个顶点的图最小生成树步骤如下: 边的权值升序排序: 选取所有未遍历的边中权

图的最小生成树(二)—Prim算法

上一篇中写了图的最小生成树求法一--Kruskal算法 http://blog.csdn.net/wtyvhreal/article/details/43526695 这一篇中用另外一种方法来求解图的最小生成树,Prim算法. 图中随便选一个顶点开始,看看这个顶点有哪些边,在它的边中找一条最短的.1号有1-2,1-3,其中1-2短,选择1-2.通过它把1和2连接在一起.接下来开始枚举1和2号顶点所有的边,看看哪些边可以连接到没有被选中的顶点,并且边越短越好. Prim算法的基本思路: 将图中的所

最小生成树算法 1.Prim算法

最小生成树(MST):一个有N个点的图,边一定是大于等于N-1条边的.在这些边中选择N-1条出来,连接所有N个点.这N-1条边的边权之和是所有方案中最小的. Prim算法的时间复杂度时O(n^2)的,因此适用于稠密图的最小生成树,如果是稀疏图的情况下采用Kruskal算法更好. Prim算法蕴含了贪心的思想,其原理是把图中所有的点分成两个集合,一个集合(V)是已经在生成树中的点,另一个集合(G)是不在生成树中的点,然后寻找起点在V中,终点在G中的边中权值最小的边加入生成树,然后把终点从G移到V中

最小生成树(1)—— Prim算法

[问题描述] N个村庄之间建立通信联络网,如何选择使得在经费最少的前提下实现全城通信. [思想分析] 假设U为所有实现通信的村庄的集合,从起点V1开始,此时U={V1},找到U与其它所有顶点权最小的边,并将V3纳入U,然后寻找U={V1,V3}与其他顶点的权最小的边,直到U={V1,V2,V3,V4,V5,V6}. [代码实现] 首先选用邻接矩阵存储图,两个顶点之间用无穷大表示无连接,用0表示彼此实现通信,其余用权值.此时,选用一个辅助结构数组closedge,包含变量adjvex和lowcos

Dijkstra算法与Prim算法辨析

这两个算法真的很像,尽管它们的用处截然不同. Dijkstra是找单源非负的最短路径. Prim是找最小生成树. Dijkstra算法都是找当前标记集合点再扩一条边所形成的最短路径,然后更新标记点集,外扩路径集. Prim是找当前标记集合点再扩一条边中所形成的的最短边,然后更新标记点集,外扩边集. 所以细节上是有不同的. Dijkstra复杂度O(N2), Prim O(eloge).