算法:最小生成树

news2024/11/23 2:43:19

文章目录

  • 生成树
  • 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();
		}

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

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

相关文章

浅谈USD格式

USD是什么&#xff1f;如何发展起来的&#xff1f; USD&#xff08;Universal Scene Description&#xff09;是一种开放的、可扩展的文件格式和数据交换标准&#xff0c;用于描述和交换三维计算机图形场景和资产的数据。它最初由皮克斯动画工作室开发&#xff0c;并于2012年公…

java答题小程序源码带后台

尊敬的客户大家好&#xff01;接下来由我来介绍一下晟讯答题小程序&#xff0c;晟讯答题小程序是一款专业性的答题小程序&#xff0c;技术方式为前端原生开发的小程序&#xff0c;服务端为java程序&#xff0c;且拥有独立知识产权&#xff0c;软著登字2019SR0657453。其功能集个…

gin使用自签名SSL证书与自签名证书不受信任方法解决

文章目录 1. X.509 V3证书介绍2、使用openssl生成自签名证书和解决不受信任问题2.1、生成根证书2.2、为域名生成证书申请文件2.3、为域名创建证书的扩展描述文件2.4、为域名创建证书 3、Go应用中使用自签名证书3.1、gin框架调用实现3.2、运行效果 4、使用java的bouncycastle生成…

ACM32如何保护算法、协议不被破解或者修改

ACM32具有以下几种功能&#xff0c;可以保护算法、协议不被破解或者修改。 1.存储保护  RDP读保护  WRP写保护  PCROP 专有代码读保护  MPU存储区域权限控制  Secure User Memory存储区域加密 2.密码学算法引擎  AES  HASH  随机数生成  …

DevEco Studio 项目启动工程和Device Manage

DevEco Studio 项目启动工程和Device Manage 鸿蒙&#xff08;HarmonyOS&#xff09; 一、操作环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、创建虚拟机&#xff08;Device Manage&#xff09; 鸿蒙IDE创建虚拟设备入口有2个地方&…

C++:this指针

目录 前言 成员函数返回this指向的对象本身时&#xff0c;为什是返回引用类型&#xff1f; 成员函数返回this对象本身时&#xff0c;内部通常会通过拷贝构造函数来创建一个临时对象&#xff1f; 总结 前言 c通过提供特殊的对象指针&#xff0c;this指针 指向被调用的成员函…

模块二——滑动窗口:438.找到字符串中所有字母异位词

文章目录 题目描述算法原理滑动窗口哈希表 代码实现 题目描述 题目链接&#xff1a;438.找到字符串中所有字母异位词 算法原理 滑动窗口哈希表 因为字符串p的异位词的⻓度⼀定与字符串p 的⻓度相同&#xff0c;所以我们可以在字符串s 中构造⼀个⻓度为与字符串p的⻓度相同…

每日好题:原来你也玩三国杀(DP动态规划)

I - 原来你也玩三国杀 Description 小 Q 最近听说 “很多” acmer 都爱上了一款游戏《三国杀》。因为小 Q 是一个初学者&#xff0c;所以想自己先偷偷学习一下&#xff0c;然后惊艳所有人。但又因为小 Q 不屑于使用一般的武将&#xff0c;因为他觉得唯有操作型武将才能显得自…

虾皮选品网:如何使用虾皮选品数据软件提升您的选品策略

在虾皮&#xff08;Shopee&#xff09;平台上进行选品时&#xff0c;了解市场趋势、竞争程度和产品潜力是非常重要的。为了帮助卖家更好地分析虾皮市场&#xff0c;并为选品和运营策略提供有力支持&#xff0c;有一些数据软件和工具可以派上用场。本文将介绍一些建议使用的虾皮…

Kafka-集群架构设计

Kafka的Zookeeper元数据梳理 zookeeper整体数据 Kafka将状态信息保存在Zookeeper中&#xff0c;这些状态信息记录了每个Kafka的Broker服务与另外的Broker服务 有什么不同。通过这些差异化的功能&#xff0c;共同体现出集群化的业务能力。这些数据&#xff0c;需要在集群中各个…

DS二分查找_搜索二维矩阵(纯二分查找写法)

本题我写了两个方法&#xff0c;一个是的时间复杂度,就是本文章一个mn时间复杂度&#xff0c;这个比较简单&#xff0c;如果不会二分法可以看这篇文章 Description 使用二分查找法来判断m*n矩阵matrix中是否存在目标值target。 该矩阵有以下特性&#xff1a; 1. 每行中的整数…

智物发布MT6877平台无线AR智能眼镜参考设计,推动下一代无线AR发展

随着增强现实(AR)技术的不断发展&#xff0c;有线AR眼镜在连接和使用方面存在一些限制。为了解决这些问题&#xff0c;无线AR智能眼镜的推出势在必行。 新一代无线AR智能眼镜采用了天玑900&#xff08;MT6877&#xff09;平台作为参考设计&#xff0c;搭载了2.4GHz的八核处理器…

【每日一题】用邮票贴满网格图

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;二维前缀和二维差分 写在最后 Tag 【二维前缀和】【二维差分】【矩阵】【2023-12-14】 题目来源 2132. 用邮票贴满网格图 题目解读 在 01 矩阵中&#xff0c;判断是否可以用给定尺寸的邮票将所有 0 位置都覆盖住&…

飞轮储能一次调频并网三机九节点系统,虚拟惯性和下垂控制,也可加入虚拟同步机VSG控制,飞轮储能容量可调,系统频率50Hz,离散模型

5MW飞轮储能一次调频并网三机九节点系统&#xff0c;虚拟惯性和下垂控制&#xff0c;也可加入虚拟同步机VSG控制&#xff0c;飞轮储能容量可调&#xff0c;系统频率50Hz&#xff0c;离散模型&#xff0c;仿真运行速度快。 飞轮储能变流器采用双PWM环设计&#xff0c;并网电压电…

CleanMyMac2024绿色免费激活码序列号

2024CleanMyMac免费mac下载版是一款简单实用的PC清洁管理工具&#xff0c;电脑刚装完系统的时候运行速度超级快&#xff0c;随着时间的推移&#xff0c;你会发现越来越慢&#xff0c;经常会反应卡顿&#xff0c;越来越多的垃圾文件占用了你的磁盘空间&#xff0c;各种过时的日志…

数据结构学习 12字母迷宫

dfs 回溯 剪枝 这个题和dfs有关&#xff0c;但是我之前没有接触过&#xff0c;我看了这一篇很好的文章&#xff0c;看完之后写的答案。 我觉得很好的总结&#xff1a; dfs模板 int check(参数) {if(满足条件)return 1;return 0; }void dfs(int step) {判断边界{相应操作}尝试…

HPV为什么无症状?皮肤性病科专家谭巍解读具体原因

HPV&#xff0c;即人乳头瘤病毒&#xff0c;是一种常见的性传播疾病。然而&#xff0c;并不是所有感染HPV的人都会出现症状。为什么有的人感染HPV没有症状呢? 首先&#xff0c;需要了解的是&#xff0c;HPV感染是一种非常常见的现象。事实上&#xff0c;大约有80%的性活跃人群…

SLAM学习——相机模型(针孔+鱼眼)

针孔相机模型 针孔相机模型是很常用&#xff0c;而且有效的模型&#xff0c;它描述了一束光线通过针孔之后&#xff0c;在针孔背面投影成像的关系&#xff0c;基于针孔的投影过程可以通过针孔和畸变两个模型来描述。 模型中有四个坐标系&#xff0c;分别为world&#xff0c;c…

智能指针管理“newed对象”

为什么要有智能指针&#xff1f; 指针智能是管理管理动态内存分配对象的一种机制。它提供了自动管理内存&#xff0c;避免常见内存泄漏和悬空指针。 对于上述Func函数的操作&#xff0c;一不小心就会产生很多问题。 p1 new时候抛异常 什么都不做p2 new时候抛异常 p1需要被清理…

SpringBoot 接口实现幂等性,实现的四种方案!

什么是接口幂等性 在HTTP/1.1中&#xff0c;对幂等性进行了定义。它描述了一次和多次请求某一个资源对于资源本身应该具有同样的结果&#xff08;网络超时等问题除外&#xff09;&#xff0c;即第一次请求的时候对资源产生了副作用&#xff0c;但是以后的多次请求都不会再对资…