最小生成树(MST,kruskal算法)

本文介绍了Kruskal算法构造最小生成树的原理和步骤,通过按照边的权重排序,结合并查集避免形成环,逐步构建权值最小的生成树。并提供了C++实现模板。
摘要由CSDN通过智能技术生成

前言

最小生成树,对于一个无向图联通且不含圈的图称为树
给定无向图G=(V,E),连接G中所有点,且边集是E的子集的数称为G的生成树(Spanning Tree),而权值最小的生成树称为最小生成树(Minimal Spanning Tree, MST)。构造MST的算法有很多,最常见的有两个:Kruskal算法和Prim算法。这里只介绍Kruskal算法,因为这个算法编写容易且效率很高。

前面描述不清楚的话,可以看下图
在这里插入图片描述
这是一个无向图,每条边有权重,你可以采用几条边就能连接所有的点,就得到了一颗生成树(前提是不含圈)。如果树的所有边的权值之和最小,就称为最小生成树。

算法流程

Kruskal算法的流程非常简单和直接:

  • 1、对于边集E,对所有的边按照权值从小到大排序
  • 2、 依次将排序好的边放入MST中,如果加入这条边(u,v)使图出现了环,则放弃
  • 3、直到所有的点都出现在MST中,构造完成。

其中第2步可能出现环,则需要检验环,这里可以采用DFS或者BFS的方式进行图遍历(写起来很复杂,需要判断什么样才算是环,而且复杂度很高)。所以我们采用另外一种方式来进行检验,那就是"并查集"。并查集可以查看我之前的博文并查集解释

另外第2步会出现的情况就是已经有几个边入选但是构不成树,如下图所示:
在这里插入图片描述
事实上我们并不需要马上构成树,我们只需要将边选出来,然后构造点的集合就可以了,这也就是为什么要用并查集的另一个理由,例如上图中有三个集合,分别是{4,6},{2,5},{1,3,}。如果连同了,那两个集合就合并为一个集合。其他还没有边连接的点构成另外的集合,例如{7},{8},{9}…

那并查集如何判断环呢?其实只要判断边的两个端点(u,v)是否在同一个集合中,如果在同一个集合中,说明已经联通(构成树),你再添加就会构成环。
以上,kruskal算法应该解释清楚了。

C++模板

struct Edge{
   
	int from, to, cost;
	Edge(int from, int to, int cost){
   this->from = from; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值