贪心算法——最小生成树Kruskal算法

最小生成树Kruskal算法

最小生成树(MST)是图论当中一个重要的算法,在实际生活中具有广泛的应用。有多种算法可以解决最小生成树问题,这里介绍Kruskal算法

问题描述

​在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边,而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树。
最小生成树其实是最小权重生成树的简称。

分析设计

Kruskal算法是解决最小生成树问题的经典算法之一。
解决最小生成树最常用的两种算法,一种是Kruskal算法,一种是Prim算法。

  • Prim算法详见博客https://blog.csdn.net/weixin_42182525/article/details/100016792

下面介绍Kruskal算法。

其主要思想是:

  1. 出发;将图中所有边按权值从小到大排序,按顺序取边;
  2. 从最小权值边开始,判断边的两个顶点是否在MST中,这里存在三种情况:
    (1)两个顶点都不在MST中,将两个顶点加入到MST中;
    (2)两个顶点其中一个在MST中,另一个不在MST中,同样,把这条边也加入到MST中;
    (3)这种情况也是最为复杂的一种,两个顶点都在MST中:经过了上面两种情况的连线MST后,可能会出现MST中的边不相连的情况(如图)
    在这里插入图片描述
    这时,需要新加入MST的一条边又可以分为两种情况,若两个顶点分属不同的连通子图(连通子MST),则可以直接将邻接边加入到MST中;反之,若两个顶点都在同一子MST中,则可能造成回路,而生成树不能有回路,因此我们要舍弃;

如图所示
在这里插入图片描述
根据第1、2步的要求,我们找到当前不在MST的边中,权值最小的:v2v4 = 3,此时我们就需要判断是否能将v2v4放入MST中。很显然,不能,这样就会产生回路
,因为v2和v4同属于同一个子MST,所以我们选择放弃这条边。
我们继续考虑下一步,下一条满足条件的边是v4v7 = 4。这时我们就可以将这条边放入MST中了,因为v4和v7属于不同的子MST,不会产生回路。

  1. 重复第二步,直至所有顶点都在MST中,即最小生成树构造完成。

在这里插入图片描述

gif制作来源于VisuAlgo https://visualgo.net/zh/mst?slide=1

以上就是Kruskal算法的基本思路了,接下来就是具体实现。

  1. 我们这里不再采用二维数组邻接矩阵的形式储存图(一开始我仍然采用该数据结构,可后面发现在这里用处不大,若有其他函数,自行更改)。那我们采用什么数据结构呢?
    我们发现,在Kruskal中边起到了关键作用,因此我们先构造一个把保存边的结构体,保存边的两个顶点,边的权值。这样我们就可以采用一维数组的形式存储图了。
    我们还可以将数据结构进一步优化。
    我们发现,我们需要对边进行排序,然后每条边按顺序取,且每条边只用到了一次………………优先队列 (这里不再讲述优先队列的用法、定义)简而言之,优先队列就是可以自动排序的队列,在这里就满足了我们的需求。
    (有人可能会说用数组+排序也是可以的。当然可以,而且从时间复杂度来看,两者没什么区别。我使用优先队列图个方便。)
  2. Kruskal中的难点。在上面的分析中,第2步中前两种情况都很好判断,最后一种情况,判断两个顶点是否在同一子MST中,是Kruskal的难点也是关键部分。
    在这里我们用到了一个数据结构:并查集:当两个集合相互合并时,判断两个集合是否为同一个。可以很好的满足我们的需求:判断两个顶点是否输入同一个集合。
    并查集的写法在这里我们不在说明。详细写法参考:https://blog.csdn.net/niushuai666/article/details/6662911

源代码

#include<iostream>
#include <vector>
#include <queue>

using namespace std
  • 4
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值