图论基础——最小生成树

树、图与生成树的定义

树:

需要保证到达每个点只有通过唯一的路径,即每两个点间只有唯一的边,且不会存在交叉的边;

图:

没有限制,点与点之间可以有很多边存在,路径也可以交叉;

生成树:

是在图的基础上,保证每个点相连,抽象出来的新的图;由于选择路径不同,一个图可以有多种生成树;
生成树必须保证图为无向图;
生成树特点:

  1. 节点数量和图的结点数量一致;
  2. n个结点,生成树有n-1条边;
最小生成树:

所有生成树中所有边的权值最小的生成树为该图的最小生成树;

计算最小生成树的算法

以洛谷3366题 最小生成树模板题为例:

①Kruskal算法:

对边按权值从小到大进行排序,按照次序进行遍历,假如该边两点不在生成树中就添加进行,假如已经存在就不添加;
所以Kruskal算法本质上是对边进行遍历;
代码实现:
预处理部分,边需要存储起点,终点和权值,由于需要对边的权值进行排序,所以需要重写操作符<;
由于需要判断新加入的边是否已经被连通了,所以需要用到简易的并查集,假如遍历到的边的起点和终点没有被连通,才把这条边加进来;
在这里插入图片描述
首先需要初始化并查集,以及接收边的信息,接收之后对边按照边的权值进行排序,排序后对边进行遍历,正如上面所说,只有遍历到一条边的起点和终点没有被加入过时,才会把这条边加进来;当边的总数达到n-1时,遍历就结束了;
在这里插入图片描述

②Prim算法:

Kruskal算法本质上是对边的遍历,而prim算法是对点的遍历。而整个过程与dijkstra算法非常相近,需要用一个优先队列来维护每个结点,并且每次都取当前优先队列中权值最小的那条边来进行;
代码实现:
预处理边,采用链式前向星进行保存边的信息,同样需要一个结点结构,由于需要用优先队列来按照边的权值维护,所以需要重写操作符;
在这里插入图片描述
加完边后,首先将起点进入优先队列,并将边的权值记录在终点处,这个地方后面仔细分析;然后每次都取优先队列中维护的结点中权值最小的边,将这条边加入进来了,并且将终点当作起点,与起点所有相连的边加入优先队列;当遍历点的个数达到n个时,遍历就结束了;
在这里插入图片描述
但是这里面有两个优化,首先是mark数组,当这个点已经被遍历过,代表以这个点为起点,所有的点都在队列内部,那这个点就不必再被遍历一次;
第二个地方是依然采取num数组记录以i点为终点最小权值大小,假如不去记录和判断也是没有问题的,但是可以减少遍历次数;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值