算法:最小生成树

文章目录

  • 生成树
  • Kruskal算法
  • Prim算法

本篇总结的是最小生成树算法

生成树

连通图中的每一棵生成树,都是原图的一个极大无环子图,即:从其中删去任何一条边,生成树就不在连通;反之,在其中引入任何一条新边,都会形成一条回路。若连通图由n个顶点组成,则其生成树必含n个顶点和n-1条边。因此构造最小生成树的准则有三条:

  1. 只能使用图中的边来构造最小生成树
  2. 只能使用恰好n-1条边来连接图中的n个顶点
  3. 选用的n-1条边不能构成回路
    构造最小生成树的方法:Kruskal算法和Prim算法。这两个算法都采用了逐步求解的贪心策略
    贪心算法:是指在问题求解时,总是做出当前看起来最好的选择。也就是说贪心算法做出的不是整体
    最优的的选择,而是某种意义上的局部最优解。贪心算法不是对所有的问题都能得到整体最优解

Kruskal算法

任给一个有n个顶点的连通网络N={V,E}

首先构造一个由这n个顶点组成、不含任何边的图G={V,NULL},其中每个顶点自成一个连通分量,其次不断从E中取出权值最小的一条边(若有多条任取其一),若该边的两个顶点来自不同的连通分量,则将此边加入到G中。如此重复,直到所有顶点在同一个连通分量上为止

核心:每次迭代时,选出一条具有最小权值,且两端点不在同一连通分量上的边,加入生成树

以下面这个图为例,模拟一次最小生成树的过程

在这里插入图片描述

下面进行这个生成树的代码实现逻辑

在这里插入图片描述
整体来说就是最小生成树的逻辑,那么基于这个逻辑就可以完成代码的编写了

// 利用Kruskal算法求最小生成树
W Kruskal(Self& mintree)
{
	mintree._matrix.resize(_matrix.size());
	for (auto& e : mintree._matrix)
		e.resize(_matrix[0].size());
	mintree._vertexs = _vertexs;
	mintree._vIndexMap = _vIndexMap;
	// 顶点之间的连通性可以用并查集来表示,选点可以用优先级队列来选
	UnionFindSet ufs(_vertexs.size());
	priority_queue < Edge, vector<Edge>, greater<Edge>> minheap;
	// 把顶点的信息存储到优先级队列中
	for (size_t i = 0; i < _matrix.size(); i++)
		for (size_t j = 0; j < _matrix[i].size(); j++)
			minheap.push(Edge(i, j, _matrix[i][j]));
	W maxW = W();
	while (!minheap.empty())
	{
		Edge cur = minheap.top();
		minheap.pop();
		// 如果当前边对应的两个顶点不连同,那么就可以作为最小边
		if (!ufs.IsSame(cur._dsti, cur._srci))
		{
			ufs.merge(cur._dsti, cur._srci);
			mintree._AddEdge(cur._srci, cur._dsti, cur._w);
			maxW += cur._w;
		}
	}
	return maxW;
}

Prim算法

在这里插入图片描述

以上面的步骤为例,完整的进行一次Prim算法的实现过程
在这里插入图片描述
下面用代码来实现一下Prim算法

		// 利用Prim算法求最小生成树
		W Prim(const V& Vertex, Self& mintree)
		{
			// 进行初始化
			mintree._matrix.resize(_matrix.size());
			for (auto& e : mintree._matrix)
				e.resize(_matrix[0].size(), W_MAX);
			mintree._vertexs = _vertexs;
			mintree._vIndexMap = _vIndexMap;
			// 用一个set集合存储的是已经使用过的顶点信息
			set<size_t> inset;
			priority_queue<Edge, vector<Edge>, greater<Edge>> minheap;
			size_t srci = GetVertexsIndex(Vertex);
			inset.insert(srci);
			// 把和这个顶点相连的边的信息都存储起来
			for (size_t i = 0; i < _matrix[srci].size(); i++)
				if (_matrix[srci][i] != W_MAX)
					minheap.push(Edge(srci, i, _matrix[srci][i]));
			W totalw = W();
			while (inset.size() < _vertexs.size() && !minheap.empty())
			{
				// 把最小权值的边取出来
				Edge minEdge = minheap.top();
				minheap.pop();
				// 如果这个边的两个顶点有一个不在集合中,那么就可以构成一个不会变成环的树
				if (inset.find(minEdge._dsti) == inset.end() || inset.find(minEdge._srci) == inset.end())
				{
					// 那么这个边就可以被使用
					//cout << _vertexs[minEdge._srci] << "->" << _vertexs[minEdge._dsti]<<" " << minEdge._w << endl;
					mintree._AddEdge(minEdge._srci, minEdge._dsti, minEdge._w);
					totalw += minEdge._w;
					// 再把和这个边相邻的边都加到队列中,供下一次寻找使用
					for(size_t i = 0; i < _matrix[minEdge._dsti].size(); i++)
						if (_matrix[minEdge._dsti][i] != W_MAX && inset.find(i) == inset.end())
							minheap.push(Edge(minEdge._dsti, i, _matrix[minEdge._dsti][i]));
					inset.insert(minEdge._dsti);
				}
			}
			if (inset.size() == _vertexs.size()) 
				return totalw;
			else
				return W();
		}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

路由器交换机配置备份工具

本文主要介绍fast-backup 2.0软件的使用&#xff0c;fast-backup 2.0是可以在任何Windows系统上运行的网络运维软件&#xff0c;帮助运维人员减少大量重复的交换机等设备的配置下载工作&#xff0c;支持的厂商有华为和华三的网络设备和安全设备。 功能特性&#xff1a; 支持S…

提升数据分析效率:Amazon S3 Express One Zone数据湖实战教程

前言 什么是 Amazon S3&#xff1f;什么是 S3 Express One Zone&#xff1f;实现概述 技术架构组件实现步骤概览 第一步&#xff1a;构建数据湖的基础第二步&#xff1a;选择并查看数据集第三步&#xff1a;在 Athena 中搭建架构第四步&#xff1a;数据转换与优化第五步&#x…

数组笔试题解析(下)

数组面试题解析 字符数组 &#xff08;一&#xff09; 我们上一篇文章学习了一维数组的面试题解析内容和字符数组的部分内容&#xff0c;我们这篇文章讲解一下字符数组和指针剩余面试题的解析内容&#xff0c;那现在&#xff0c;我们开始吧。 我们继续看一组字符数组的面试…

binkw32.dll丢失怎么办?这5个方法都可以解决binkw32.dll丢失问题

binkw32.dll文件是什么&#xff1f; binkw32.dll是一个动态链接库文件&#xff0c;它是Windows操作系统中的一个重要组件。它包含了许多用于处理多媒体文件的函数和资源&#xff0c;如视频、音频等。当我们在电脑上打开或播放某些多媒体文件时&#xff0c;系统会调用binkw32.d…

【算法】滑动窗口

目录 基本思想 应用场景 应用实例 总结 基本思想 滑动窗口&#xff0c;也叫尺取法&#xff0c;就是不断的调节子序列的起始位置和终止位置&#xff0c;从而得出我们要想的结果&#xff0c;可以用来解决一些查找满足一定条件的连续区间的性质&#xff08;长度等&#xff09;…

【活动回顾】Databend 云数仓与 Databend Playground 扩展组件介绍

2023 年 12 月 7 日&#xff0c;作为 KubeSphere 的合作伙伴&#xff0c;Databend 荣幸地受邀参与了 KubeSphere 社区主办的云原生技术直播活动。本次活动的核心议题为「Databend 云数仓与 Databend Playground 扩展组件介绍」&#xff0c;此次分享由 Databend Labs 的研发工程…

Vue3-08-条件渲染-v-if 的基本使用

v-if 是什么 v-if 一个指令&#xff0c; 它是用来根据条件表达式&#xff0c;进行选择性地【展示】/【不展示】html元素的。比如 &#xff1a; 有一个按钮A&#xff0c;当条件为真时&#xff0c;展示该按钮&#xff1b;条件为假时&#xff0c;不展示该按钮。与 js 中的 条件判…

如何部署Portainer容器管理工具+cpolar内网穿透实现公网访问管理界面

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 本文主要介绍如何本地安装Portainer并结合内网穿透工具实现任意浏览器远程访问管理界面。Portainer 是一个轻量级…

一文5000字从0到1构建高效的接口自动化测试框架思路

在选择接口测试自动化框架时&#xff0c;需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说&#xff0c;使用Python相关的测试框架更为便捷。无论选择哪种框架&#xff0c;重要的是确保 框架功能完备&#xff0c;易于维护和扩展&#xff0c;提高测试效率和准确性。…

挺进云存储,天翼云全新一代XSSD勇立潮头

引言&#xff1a;自研高性能分布式存储引擎LAVA&#xff0c;实现云硬盘持续创新获得新突。 【全球云观察 &#xff5c; 科技热点关注】 作为算力基础设施的基石&#xff0c;云存储的发展一直备受公有云厂商所重视&#xff0c;对拉动云厂商营收规模带来重要价值&#xff0c;就…

山海鲸开发者:展现数据可视化在各领域的无限可能

作为一名山海鲸可视化软件的内部开发者&#xff0c;我对这款软件投入了大量的经历以及含有深深的情感。下面&#xff0c;我从这款软件应用场景下手&#xff0c;带大家探秘这款软件的多种可能性以及我们的用心。 首先&#xff0c;从行业角度来看&#xff0c;山海鲸可视化软件可以…

06.迪米特法则(Demeter Principle)

明 嘉靖四十年 江南织造总局 小黄门唯唯诺诺的听完了镇守太监杨金水的训斥&#xff0c;赶忙回答&#xff1a;“知道了&#xff0c;干爹&#xff01;” “知道什么&#xff1f;&#xff01;&#xff01;” 杨金水打断了他的话&#xff0c;眼神突然变得凌厉起来&#xff1a; “有…

椋鸟C语言笔记#26:数据在内存中的存储(大小端字节序)、浮点数的存储(IEEE754)

萌新的学习笔记&#xff0c;写错了恳请斧正。 目录 大小端字节序 什么是大小端 写一个判断大小端的程序 浮点数在内存中的存储&#xff08;IEEE 754规则&#xff09; 引入 存储规则解释 读取规则解释 1.阶码不全为0或全为1&#xff08;规格化数&#xff09; 2.阶码全为…

鸿蒙系统走向独立,高校设立“鸿蒙班”,鸿蒙人才紧缺!

近日&#xff0c;华为以及鸿蒙系软件厂商都在积极培养鸿蒙开发人才&#xff0c;产学联动、产教融合是重要的一条路径。目前已有23家985高校、46家211高校已开设或即将开设HarmonyOS相关课程。 一位鸿蒙生态内部人士表示&#xff0c;目前鸿蒙开发人才比较紧缺&#xff0c;而安卓…

图生视频AI技术,1张图零提示词,让静态照片动起来

AI时代的发展速度比我们想象中的快多了&#xff0c;当大部分人刚学会AI生成图片时&#xff0c;现在又开始流行AI生成视频了&#xff0c;正式从图片、文字升级到短视频时代。 最近一段时间&#xff0c;AI生成视频的技术正在突飞猛进。Pika、Runway等大家熟知的海外工具都在不断…

【STM32CubeMX】F103 BxCAN

F103&BxCAN bxCAN总体描述 有一个增强的过滤机制来处理各种类型的报文此外&#xff0c;应用层任务需要更多CPU时间&#xff0c;因此报文接收所需的实时响应程度需要减轻。 接收FIFO的方案允许&#xff0c;CPU花很长时间处理应用层任务而不会丢失报文。 构筑在底层CAN驱动程…

软件设计中如何画各类图之七了解组件图:系统架构的关键视角

目录 1 前言2 组件图基本介绍3 画组件图的步骤4 组件图的用途5 场景及实际场景举例6 结语 1 前言 组件图是一种UML的图形化表示工具&#xff0c;为系统架构提供了重要视角。它描述了系统中各个组件以及它们之间的依赖关系和连接。用于展示系统中的组件、软件模块、以及它们之间…

简单实现Spring容器(五) 实现bean后置处理器BeanPostProcessor机制

阶段5: // 1.编写自己的Spring容器,实现扫描包,得到bean的class对象. // 2.扫描将 bean 信息封装到 BeanDefinition对象,并放入到Map. // 3.初始化单例池并完成getBean() createBean()方法 // 4.完成依赖注入(如果创建某个Bean对象,存在依赖注入,需要进行bean组装操作) 5.bean…

比较好的python书籍,python有什么书推荐

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;比较好的python书籍&#xff0c;python有什么书推荐&#xff0c;现在让我们一起来看看吧&#xff01; 我是在半年前接触到Python的&#xff0c;我之前没有一点编程基础&#xff0c;但在我自学的这半年里&#xff0c;我发…

绿盟 SAS堡垒机 local_user.php 权限绕过漏洞复现

绿盟 SAS堡垒机 local_user.php 权限绕过漏洞复现 一、 产品简介二、漏洞概述三、 复现环境四、漏洞复现五、小龙检测 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&…