Kruskal算法求最小生成树

求加权连通图的最小生成树的算法。kruskal算法总共选择n-
1条边,(共n条边)所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。kruskal算法分e
步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。

克鲁斯卡尔算法(Kruskal‘s algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。大致的流程可以用一个图来表示。这里的图的选择借用了Wikipedia上的那个。非常清晰且直观。

首先第一步,我们有一张图,有若干点和边

第一步我们要做的事情就是将所有的边的长度排序,用排序的结果作为我们选择边的依据。这里再次体现了贪心算法的思想。资源排序,对局部最优的资源进行选择。

排序完成后,我们率先选择了边AD。这样我们的图就变成了

.

.

.

.

.

.

第二步,在剩下的边中寻找。我们找到了CE。这里边的权重也是5

.

.

.

.

.

.

依次类推我们找到了6,7,7。完成之后,图变成了这个样子。

.

.

.

.

.

.

下一步就是关键了。下面选择那条边呢? BC或者EF吗?都不是,尽管现在长度为8的边是最小的未选择的边。但是他们已经连通了(对于BC可以通过CE,EB来连接,类似的EF可以通过EB,BA,AD,DF来接连)。所以我们不需要选择他们。类似的BD也已经连通了(这里上图的连通线用红色表示了)。

最后就剩下EG和FG了。当然我们选择了EG。最后成功的图就是下图:

.

.

.

.

.

.

到这里所有的边点都已经连通了,一个最小生成树构建完成。

Kruskal算法的时间复杂度由排序算法决定,若采用快排则时间复杂度为O(N log N)。

时间: 2024-07-29 23:42:59

Kruskal算法求最小生成树的相关文章

利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地 表还是被大水淹没着,部分植物的树冠露在水面上.猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面 的不同树冠上来回穿梭,以找到喜欢吃的果实.现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都 很小,可以忽略不计.我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表

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

Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小生成树中一定有n-1条边. Prim算法需要两个线性表来进行辅助: visited: 标记已经加入生成树的顶点:(它的功能可以由tree取代) 初始状态:生成树根节点为真,其它为0. tree: 记录生成树,tree[x]保存顶点x的直接根节点下标,若x为树的根节点则tree[x]为其自身. 初始状

kruskal算法求最小生成树(jungle roads的kruskal解法)

注意: 注意数组越界问题(提交出现runtimeError代表数组越界) 刚开始提交的时候,边集中边的数目和点集中点的数目用的同一个宏定义,但是宏定义是按照点的最大数定义的,所以提交的时候出现了数组越界问题,以后需要注意啦. Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads betwe

Prime算法求最小生成树 (邻接表)

/* Name: Prime算法求最小生成树 (邻接表) Copyright: Author: 巧若拙 Date: 25/11/14 13:38 Description: 实现了 Prime算法求最小生成树 (邻接表)的普通算法和最小堆优化算法. */ #include<stdio.h> #include<stdlib.h> #define MAX 2000   //最大顶点数量 #define INFINITY 999999   //无穷大 typedef int VertexT

Prime算法求最小生成树 (邻接矩阵)

/* Name: Prime算法求最小生成树 (邻接矩阵) Copyright: Author: 巧若拙 Date: 25/11/14 13:38 Description: 实现了 Prime算法求最小生成树 (邻接矩阵)的普通算法和最小堆优化算法. */ #include<stdio.h> #include<stdlib.h> #define MAX 2000   //最大顶点数量 #define INFINITY 999999   //无穷大 typedef struct Mi

最小生成树 克鲁斯卡尔(Kruskal)算法求最小生成树

Kruskal算法的过程: (1) 将全部边按照权值由小到大排序. (2) 按顺序(边权由小到大的顺序)考虑没条边,只要这条边和我们已经选择的边步构成圈,就保留这条边,否则放弃这条边.算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通. 图中的路径按照权值的大小的排序为 AF 1; BE 4; BD 5; BC 6; DC:10; BF 11; DF 14; AE 16; AB 17; EF 33; 算法的处理过程如下 先选A,F不在一个

hdu 1875 畅通工程再续(kruskal算法计算最小生成树)

畅通工程再续 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 18411    Accepted Submission(s): 5769 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现.现在政府决定大力发展百岛湖,发展首先

Kruskal算法(最小生成树)

Kruskal算法:首先按照边的权值进行从小到大排序,每次从剩余的边中选择权值最小的边且不会产生回路的边加入到生成树中,直到加入n-1条边就结束: 算法难点在与如何判断是否会产生回路.这个可以通过并查集实现,将所有加入生成树的结点加入同一个集合: 代码: #include <string.h> #include<iostream> #include<vector> #include<queue> #include <algorithm> usin

Kruskra算法求最小生成树

算法思想: (1)创建图,将每个节点的根节点,标记为-1. (2)对图中的边按权重排序 (3)遍历每条边,获取边两端的根节点 如果两个端点的根节点相等,且均是-1,则代表这是一条孤立的边(同时修改目的节点的父节点设为源节点),把这条边计入生成树 如果两个端点的根节点相等,且不是-1(可能是-2,-3,之类),这说明加入这条边构成环路,不需要任何操作 如果两个端点的根节点不相等,这说明这条边连接了两棵树,(同时修改目的节点根节点的父节点设为源节点),把这条边计入生成树 注:其实我们知道最小生成树,