408数据结构-图的应用1-最小生成树 自学知识点整理

news2024/11/29 9:00:15

前置知识:图的遍历


图的应用是408初试历年考查的重点。不过一般而言,这部分内容直接以算法设计题形式考查的可能性极小,更多的是结合图的实例来考查算法的具体操作过程,要求掌握的是手推模拟给定图的各个算法执行过程。此外,还需对给定模型建立相应的图去解决问题。

最小生成树

知识点回顾:图的基本概念-生成树

一个连通图的生成树包含图的所有顶点,并且只含尽可能少的边。对于生成树来说,若砍去(减少)它的一条边,则会使生成树变成非连通图;若给它增加一条边,则会形成图中的一条回路(环)。
对于一个带权连通无向图 G G G,生成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同。权值之和最小的那棵生成树称为 G G G的最小生成树( M i n i m u m − S p a n n i n g − T r e e Minimum-Spanning-Tree MinimumSpanningTree M S T MST MST)。

最小生成树的性质

  1. 若图 G G G中存在权值相同的边,则 G G G的最小生成树可能不唯一,即最小生成树的树形可能不唯一。当图 G G G中的各边权值互不相等时, G G G的最小生成树是唯一的;若无向连通图 G G G的边数比顶点数少 1 1 1,即 G G G本身是一棵树时,则图 G G G的最小生成树就是其本身;只有连通图才有生成树,非连通图只有生成森林。
  2. 虽然最小生成树可能不唯一,但其对应的边的权值之和总是唯一的,并且是最小的。
  3. 最小生成树的边数为顶点数减 1 1 1。(树的性质)

注意:最小生成树中所有边的权值之和最小,不代表任意两个顶点之间的路径是最短路径。

构造最小生成树有多种算法,但大多数算法都利用了最小生成树的下列性质:假设 G = ( V , E ) G=(V,E) G=(V,E)是一个带权连通无向图, U U U是顶点集 V V V的一个非空子集。若 ( u , v ) (u,v) (u,v)是一条具有最小权值的边,其中 u ∈ U , v ∈ V − U u∈U, v∈V-U uU,vVU,则必存在一棵包含边 ( u , v ) (u,v) (u,v)的最小生成树。

基于该性质的最小生成树算法主要有 P r i m Prim Prim算法和 K r u s k a l Kruskal Kruskal算法,它们都是基于贪心算法的策略,即通过多个局部最优解得到全局最优解。408初试中,需要掌握这两个算法的本质含义和基本思想,并能够手动模拟推演出其算法的实现步骤。
王道书上给出了一个通用的最小生成树算法的伪代码:

GENERIC_MST(G) {
	T=NULL;
	while T 未形成一棵生成树;
		do 找到一条最小代价边(u,v)并加入T后不会产生回路;
			T=T∪(u,v);
}

P r i m Prim Prim算法

P r i m Prim Prim(普里姆)算法的执行非常类似于寻找图的最短路径的 D i j k s t r a Dijkstra Dijkstra算法(下一节会讲)。

P r i m Prim Prim算法构造最小生成树的过程如下图 6.15 6.15 6.15所示(王道考研408数据结构2025 - P241)。初始时选取图中任一顶点(如顶点 1 1 1)加入树 T T T,此时树中只含有一个顶点,之后选择一个与当前 T T T中顶点集合距离最近的顶点,并将该顶点和相应的边加入 T T T,每次操作后 T T T中的顶点数和边数都增加 1 1 1。以此类推,直至图中所有的顶点都并入 T T T,得到的 T T T就是最小生成树。
(图片来自王道考研408数据结构2025)
图片来自王道考研408数据结构2025
P r i m Prim Prim算法的步骤如下:

  • 假设 G = { V , E } G= \{V,E\} G={V,E}是连通图,其最小生成树 T = ( U , E T ) T=(U,E_T) T=(U,ET) E T E_T ET是最小生成树中边的集合。
  • 初始化:向空树 T = ( U , E T ) T=(U,E_T) T=(U,ET)中添加图 G = ( V , E ) G=(V,E) G=(V,E)的任意一个顶点 u 0 u_0 u0,使 U = { u 0 } U=\{u_0\} U={u0} E T = ∅ E_T=\emptyset ET=
  • 循环(重复下列操作直至 U = V U=V U=V):从图 G G G中选择满足 { ( u , v ) ∣ u ∈ U , v ∈ V − U } \left \{ \left ( u,v \right ) \mid u \in U, v \in V-U \right \} {(u,v)uU,vVU}且具有最小权值的边 ( u , v ) (u,v) (u,v),加入树 T T T,置 U = U ∪ { v } U = U \cup \left \{ v \right \} U=U{v} E T = E T ∪ { ( u , v ) } E_T = E_T \cup \left \{ \left ( u,v \right ) \right \} ET=ET{(u,v)}

王道书上给出的 P r i m Prim Prim算法简单实现的伪代码如下,感兴趣的读者可以尝试完善之:

void Prim(G, T){
	T=;				//初始化空树
	U={w};				//添加任意一个顶点w
	while((V-U)!=){	//若树中不含全部顶点(u,v)是使u∈U与v∈(V−U),且权值最小的边
		T=T∪{(u,v)};	//边归入树
		U=U∪{v};		//顶点归入树
	}
}

P r i m Prim Prim算法的时间复杂度为 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2),不依赖于 ∣ E ∣ |E| E,因此它适用于求解稠密图的最小生成树。虽然采用其他方法能改进 P r i m Prim Prim算法的时间复杂度,但增加了实现的复杂性。

相关例题:PTA 7-50 畅通工程之局部最小花费问题(传送门)

K r u s k a l Kruskal Kruskal算法

P r i m Prim Prim算法从顶点开始扩展最小生成树不同, K r u s k a l Kruskal Kruskal(克鲁斯卡尔)算法是一种按权值的递增次序选择合适的边来构造最小生成树的方法。
K r u s k a l Kruskal Kruskal算法构造最小生成树的过程如下图 6.16 6.16 6.16所示(王道考研408数据结构2025 - P241)。初始时为只有 n n n个顶点而无边的非连通图 T = { V , { } } T = \left \{ V,\left \{ \right \} \right \} T={V,{}},每个顶点自成一个连通分量。然后按照边的权值由小到大的排序,不断选取当前未被选取过且权值最小的边,若该边依附的顶点落在 T T T中不同的连通分量上(使用并查集判断这两个顶点是否属于同一棵集合树),则将此边加入 T T T,否则舍弃此边而选择下一条权值最小的边。以此类推,直至 T T T中所有顶点都在一个连通分量上。
(图片来自王道考研408数据结构2025)
图片来自王道考研408数据结构2025

知识点回顾:并查集

K r u s k a l Kruskal Kruskal算法的步骤如下:

  • 假设 G = { V , E } G= \{V,E\} G={V,E}是连通图,其最小生成树 T = ( U , E T ) T=(U,E_T) T=(U,ET)
  • 初始化: U = V U=V U=V E T = ∅ E_T=\emptyset ET=。即每个顶点构成的一棵独立的树, T T T此时是一个仅含 ∣ V ∣ |V| V个顶点的森林。
  • 循环(重复直至 T T T是一棵树):按 G G G的边的权值递增顺序依次从 E − E T E-E_T EET中选择一条边,若这条边加入 T T T后不构成回路,则将其加入 E T E_T ET,否则舍弃,直到 E T E_T ET中含有 n − 1 n-1 n1条边。

王道书上给出的 K r u s k a l Kruskal Kruskal算法简单实现的伪代码如下,感兴趣的读者可以尝试完善之:

void Kruskal(V,T){
	T=V;						//初始化树T,仅含顶点
	numS=n;						//连通分量数
	while(numS>1){				//若连通分量数大于1
		从E中取出权值最小的边(v,u);
		if(v和u属于T中不同的连通分量){
			T=T∪{(v,u)};		//将此边加入生成树中
			numS--;				//连通分量数减1
		}
	}
}

根据图的相关性质,若一条边连接了两棵不同树中的顶点,则对这两棵树来说,它必定是连通的,将这条边加入森林中,完成两棵树的合并,直到整个森林合并成一棵树。
K r u s k a l Kruskal Kruskal算法中,最坏情况下需要对 ∣ E ∣ |E| E条边各扫描一次。通常采用堆(第 7 7 7章里会讲)来存放边的集合,每次选择最小权值的边需要 O ( l o g 2 ∣ E ∣ ) O(log_2|E|) O(log2E)的时间;每次使用并查集来快速判断两个顶点是否属于一个集合所需的时间为 O ( α ( ∣ V ∣ ) ) O(α(|V|)) O(α(V)) α ( ∣ V ∣ ) α(|V|) α(V)的增长极其缓慢,可视为常数。算法的总时间复杂度为 O ( ∣ E ∣ l o g 2 ∣ E ∣ ) O(|E|log_2|E|) O(Elog2E),不依赖于 ∣ V ∣ |V| V,因此 K r u s k a l Kruskal Kruskal算法适合顶点较多的稀疏图

相关例题:洛谷P3366 【模板】最小生成树(传送门)
个人题解:【洛谷P3366】【模板】最小生成树 解题报告

对本小节内容,需要掌握手推Prim算法和Kruskal算法过程,能够模拟构建最小生成树,如有余力可以打一些代码题增强理解。
以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1851084.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利口 202. 快乐数

力扣 202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果这个过程 结…

信号基本分析方法——频域分析

二、频域分析 随机信号的时域分析只能提供有限的时域故障特征信息,故障发生时往往会引起信号频率结构的变化,而故障频率可以计算和预知,通过检测频率的幅值变换规律,就可以监控故障的发展过程。 频谱分析的理论基础是傅里叶变换…

AI音乐模型:创新还是颠覆?

文章目录 AI音乐大模型的崛起音乐创作门槛的降低与兴奋AI音乐作品的版权归属问题创意产业在AI阴影下的生长结语 🎉欢迎来到AIGC人工智能专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页:IT陈寒的博客&…

【数据结构】链表的大概认识及单链表的实现

目录 一、链表的概念及结构 二、链表的分类 三、单链表的实现 建立链表的节点: 尾插——尾删: 头插——头删: 查找: 指定位置之后删除——插入: 指定位置之前插入——删除指定位置: 销毁链表&am…

向量和矩阵的点乘、叉乘

# 本科学习的全都还回去了-_- 一、向量 (1)点乘 向量点积, 𝑎⋅𝑏𝑐 ,符号为 ⋅ ,要求向量长度相同,是两个向量之间的点乘运算,结果是一个标量。又称&…

在 Equinix 上使用 MinIO 控制云数据成本

公有云改变了公司构建、部署和管理应用程序的方式,主要是向好的方向发展。在您刚开始使用时,公有云会提供基础架构、服务、支持和维护,以便快速启动和运行。它以几乎无限的方式提供最终的可伸缩性,无论应用程序的负载如何&#xf…

ROS中的TF是什么

在ROS (Robot Operating System) 中,tf::TransformBroadcaster 是一个用于发布坐标变换信息的重要类,尤其在处理机器人定位和导航数据时非常常见。tf::TransformBroadcaster 对象允许你广播从一个坐标系到另一个坐标系的变换关系,这对于多传感…

c语言 课设 atm

功能需求分析 ATM功能主界面:显示所能进行的操作,用户可多次选择。 ATM注册界面:输入用户名,用户密码,确认密码,密码长度不是六位重新输入,两次密码不一致重新输入,输入账号。密码隐藏,实现退格换行对*无影响。多人注册 ATM登录界面:输入账号,密码,三次以内输入…

bug记录——C语言中运算符前假后面不执行

A&&B A为真&#xff0c;才会判断B&#xff0c; 所以如果B访问越界的情况下必有A为假&#xff0c;那么代码是正确的 像这里&#xff0c;当child 1 > n时&#xff0c;a[child 1]越界访问&#xff0c; 但由于&&前面判断了child 1 < n为假&#xff0c;所以…

荒野大镖客2启动找不到emp.dll的7个修复方法,轻松解决dll丢失的办法

一、emp.dll文件丢失的常见原因 安装或更新问题&#xff1a;在软件或游戏的安装过程中&#xff0c;可能由于安装程序未能正确复制文件到目标目录&#xff0c;或在更新过程中文件被意外覆盖或删除&#xff0c;导致emp.dll文件丢失。 安全软件误删&#xff1a;某些安全软件可能…

跌倒识别:守护公共安全的AI技术应用场景-免费API调用

随着科技的不断进步&#xff0c;人工智能在各个领域的应用日益广泛&#xff0c;其中在公共安全领域&#xff0c;智能跌倒识别系统正逐渐成为守护人们安全的重要工具。本文将分享智能跌倒识别系统在不同场景下的应用及其重要性。 产品在线体验地址-API调用或本地化部署 AI算法模…

C#实现音乐在线播放和下载——Windows程序设计作业3

1. 作业内容 编写一个C#程序&#xff0c;在作业二实现的本地播放功能的基础上&#xff0c;新增在线播放和在线下载功能&#xff0c;作业二博客地址&#xff1a;C#实现简单音乐文件解析播放——Windows程序设计作业2 2. 架构选择 考虑到需求中的界面友好和跨版本兼容性&#xf…

【Linux】基础IO_3

文章目录 六、基础I/O3. 软硬链接4. 动静态库 未完待续 六、基础I/O 3. 软硬链接 使用 ln 就可以创建链接&#xff0c;使用 ln -s 可以创建软链接&#xff0c;直接使用 ln 则是硬链接。 我们对硬链接进行测试一下&#xff1a; 根据测试&#xff0c;我们知道了 硬链接就像一…

Django框架数据库ORM查询操作

Django框架在生成数据库的models模型文件后&#xff0c;旧可以在应用中通过ORM来操作数据库了。今天抽空试了下查询语句。以下是常用的查询语句。 以下查询需要引入django的Sum&#xff0c;Count&#xff0c;Q模块 from django.db.models import Sum,Count,Q 导入生成的mode…

【FreeRTOS】删除任务 用遥控器控制音乐

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 学习视频&#xff1a;【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS&#xff08;FreeRTOS教程 基于STM32&#xff0c;以实际项目为导向&#xff09;】 【精准空降到 01:22】 https://www.bilibili.com/video/BV1…

App Store苹果应用商店如何退款

这几天想在App Store找一款录音可以转文字的app&#xff0c;结果找到后需要订阅才能转文字&#xff1b;最短1个月38元&#xff0c;购买之后&#xff0c;试用了功能&#xff0c;发现转出来的文字差强人意&#xff0c;且好多语音漏过了没转出来&#xff1b;于是决定取消订阅&…

ArkUI部分案例笔记——padding,space

基础的构建 组件分类&#xff1a; 容器组件&#xff1a;像Column&#xff0c;Row这种组件就是容器组件一般就来控制行和列的就是容器组件 基础组件&#xff1a;Text(文本组件)&#xff0c;像这种用来有一定功能的就是基础组件 注意&#xff1a;一个build只能有一个根容器组件…

8.12 矢量图层面要素单一符号使用五(栅格数据填充)

文章目录 前言栅格数据填充&#xff08;Raster image fill&#xff09;QGis设置面符号为栅格数据填充&#xff08;Raster image fill&#xff09;二次开发代码实现栅格数据填充&#xff08;Raster image fill&#xff09; 总结 前言 本章介绍矢量图层线要素单一符号中使用栅格…

XXL-Job实战(千万级短信推送实战)

上回我们介绍了传统定时任务与分布式任务调度的差异以及它们的优缺点&#xff0c;本节我们使用Xxl-job来实现相关需求。 首先我们需要下载Xxl-job对应的服务端&#xff1b;下面是Xxl-job的github地址&#xff1a; Releases xuxueli/xxl-job (github.com) 版本我们选择V-2.3…

【iOS】编译二进制文件说明

编译二进制文件说明 如何生成文件路径文件说明第一部分&#xff1a;.o文件第二部分&#xff1a;link第三部分&#xff1a;Segment第四部分&#xff1a;Symbol 如何生成 使用Xcode进行编译 &#xff0c;会生成二进制相关文件&#xff0c;可以更详细看产物的布局 项目Target -&…