算法与数据结构--最小生成树算法

一.应用的场景

类似于这种最小成本问题,实际上就是计算加权图把所有点连起来权重之和最小值的时候是怎么连接的。类似的问题还有最短耗时之类的问题。

二.最小生成树的定义

生成树:
图的生成树是它的一颗含有其所有顶点无环连通子图。
【简单说就是所有顶点连接在一起,并且没有环。
因此有n个顶点,n-1的边】
最小生成树:
所有生成树中权值(树中所有边的权重之和)最小的生成树。

解决之类问题实际上就是求出最小生成树,并计算它的权值之和。

三.如何构建最小生成树

目前有两种经典的生成最小生成树的算法,Prim算法和Kruskal算法。两种算法都是基于贪婪算法的思想。

1.Kruskal算法

【1】将所有边按照权值从小到大进行排序。
【2】依次取出每条边,如果边的两个节点分别位于两棵树上,则将这两棵树合并成为一棵树;如果两个节点位于同一棵树上,则忽略这条边。
【3】等到所有的边都遍历结束之后,如果所有的生成树可以合并成一棵生成树,那么它就是我们需要寻找的最小生成树,反之则没有最小生成树。

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;// 结构体表示一条边
struct Edge {int src, dest, weight;//起点,终点,权值 
};// 结构体表示并查集
struct DisjointSet {//parent 数组存储每个元素的父节点,rank 数组存储每个集合的秩。vector<int> parent, rank;// 构造函数,初始化并查集DisjointSet(int n) {parent.resize(n);rank.resize(n, 0);// 初始化每个元素为一个独立的集合,父节点指向自身for (int i = 0; i < n; i++) {parent[i] = i;}}// 查找一个元素所属的集合,使用路径压缩优化int find(int x) {if (parent[x] != x) {parent[x] = find(parent[x]); // 路径压缩}return parent[x];}// 合并两个集合,使用秩优化void unionSets(int x, int y) {int xRoot = find(x);int yRoot = find(y);if (rank[xRoot] < rank[yRoot]) {parent[xRoot] = yRoot;} else if (rank[xRoot] > rank[yRoot]) {parent[yRoot] = xRoot;} else {parent[yRoot] = xRoot;rank[xRoot]++;}}
};// 比较函数,用于对边按权值进行排序
bool compareEdges(const Edge& a, const Edge& b) {return a.weight < b.weight;
}// 使用Kruskal算法求解最小生成树
vector<Edge> kruskalMST(vector<Edge>& edges, int numVertices) {// 对边按权值进行排序sort(edges.begin(), edges.end(), compareEdges);vector<Edge> result;DisjointSet ds(numVertices);for (const Edge& edge : edges) {int srcParent = ds.find(edge.src);int destParent = ds.find(edge.dest);// 如果加入这条边不会形成环路,则将它加入最小生成树if (srcParent != destParent) {result.push_back(edge);ds.unionSets(srcParent, destParent);}}return result;
}// 打印最小生成树的边集
void printMST(const vector<Edge>& mst) {cout << "最小生成树:" << endl;for (const Edge& edge : mst) {cout << edge.src << " -- " << edge.dest << " : " << edge.weight << endl;}
}int main() {int numVertices, numEdges;cout << "请输入顶点数:";cin >> numVertices;cout << "请输入边数:";cin >> numEdges;vector<Edge> edges(numEdges);cout << "请输入每条边的起点、终点和权值:" << endl;for (int i = 0; i < numEdges; i++) {cin >> edges[i].src >> edges[i].dest >> edges[i].weight;}vector<Edge> mst = kruskalMST(edges, numVertices);printMST(mst);return 0;
}

2.Prim算法

思路:

最优布线问题 题解_学校有 n 台计算机,为了方便数据传输,现要将它们用数据线连接起来。两台计算机被-CSDN博客

代码:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;const int INF = 1e9; // 定义无穷大// 表示图的邻接矩阵
vector<vector<int>> graph;// 使用Prim算法生成最小生成树
void prim(int n)
{vector<int> dist(n, INF); // 存储顶点到最小生成树的距离vector<bool> visited(n, false); // 记录顶点是否被访问过priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // 小顶堆int src = 0; // 从顶点0开始生成最小生成树dist[src] = 0;pq.push(make_pair(0, src));while (!pq.empty()){int u = pq.top().second;pq.pop();visited[u] = true;for (int v = 0; v < n; ++v){if (graph[u][v] != 0 && !visited[v] && graph[u][v] < dist[v]){dist[v] = graph[u][v];pq.push(make_pair(dist[v], v));}}}cout << "边\t权值" << endl;for (int i = 1; i < n; ++i){cout << i << " - " << i + 1 << "\t" << dist[i] << endl;}
}int main()
{int n; // 顶点数量cout << "请输入顶点数量: ";cin >> n;// 初始化邻接矩阵graph.resize(n, vector<int>(n));cout << "请输入邻接矩阵:" << endl;for (int i = 0; i < n; ++i){for (int j = 0; j < n; ++j){cin >> graph[i][j];}}prim(n);return 0;
}

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

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

相关文章

Java中的IO流

在Java中&#xff0c;I/O&#xff08;输入/输出&#xff09;流用于处理与输入和输出相关的操作。Java的I/O流按照数据处理的不同方式分为两大类&#xff1a;字节流和字符流。每个类别又分为输入流和输出流。以下是Java中常用的I/O流及其继承关系&#xff1a; 字节流&#xff0…

BERT Intro

继续NLP的学习&#xff0c;看完理论之后再看看实践&#xff0c;然后就可以上手去kaggle做那个入门的project了orz。 参考&#xff1a; 1810.04805.pdf (arxiv.org) BERT 论文逐段精读【论文精读】_哔哩哔哩_bilibili (强推!)2023李宏毅讲解大模型鼻祖BERT&#xff0c;一小时…

竞赛保研 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

探索芊芊简历:一个革新的简历创建工具

在寻找理想工作的道路上&#xff0c;一份出色的简历是打开机遇之门的关键。今天&#xff0c;我想向大家介绍一款名为“芊芊简历”的免费简历编辑器&#xff0c;它以其独特的功能和先进的技术&#xff0c;为求职者提供了一个简单而高效的简历制作解决方案。 丰富多样的模板&…

虚拟局域网的基本概念与基本原理

虚拟局域网&#xff08;Virtual Local Area Network&#xff0c;VLAN&#xff09;是一种在物理局域网内部划分逻辑上独立的虚拟网络的方法。它通过在网络交换机上配置&#xff0c;将不同的设备分组到不同的虚拟网络中&#xff0c;实现了逻辑上分隔的网络通信。本文将介绍虚拟局…

北京大学漏洞报送证书

获取来源&#xff1a;edusrc&#xff08;教育漏洞报告平台&#xff09; url&#xff1a;教育漏洞报告平台(EDUSRC) 兑换价格&#xff1a;30金币 获取条件&#xff1a;北京大学任意中危或以上级别漏洞

【排序】快速排序

思想 快速排序是一种基于分治策略的排序算法&#xff0c;其核心思想通过选取一个基准元素&#xff0c;将数组分成两个子数组&#xff1a;一个包含小于基准元素的值&#xff0c;另一个包含大于基准元素的值。然后递归地对这两个子数组进行排序&#xff0c;最终将它们合并起来&a…

UltraScale 和 UltraScale+ 生成已加密文件和已经过身份验证的文件

注释 &#xff1a;如需了解更多信息&#xff0c;请参阅《使用加密和身份验证确保 UltraScale/UltraScale FPGA 比特流的安全》 (XAPP1267)。 要生成加密比特流&#xff0c;请在 Vivado IDE 中打开已实现的设计。在主工具栏中&#xff0c;依次选择“Flow” → “Bitstream Setti…

解决在eclipse2021中,用mysql-connector-java-8.0.18.jar不兼容,导致无法访问数据库问题

1.环境场景 组件版本mysql5.7.44mysql-connector-java80.18 2. 问题描述 报mysql-connector-java 驱动连不上mysql数据库。 3. 可能的原因分析 查看数据库连接句柄是否对 如果数据库连接句柄中没有 useSSLfalse 的话可能会导致这样的问题。 就像下面这样&#xff1a; jdb…

FRPS配置服务端(腾讯云)、客户端(PC电脑Windows、树莓派Debian)并设置虚拟域名

1.服务端&#xff08;腾讯云&#xff09;&#xff1a;frps.ini [common] bind_port 7000 vhost_http_port8080 vhost_https_port44344 dashboard_port 7500 privilege_token your_password subdomain_host example.com use_encryption true encryption_method tls dashb…

搭建zuul网关

1. 路由知识 有关网关的很多知识我们都在04.gateway讲解了&#xff0c;有关网关的详细知识可以到上节详细了解。本节我们主要来讲解下另一个网关zuul。本节结合之前的章节网关搭建的项目案例上实现zuul的搭建&#xff0c;侧重于实战。 2. Zuul现状 zuul官方文档 zuul截止clo…

【ZooKeeper高手实战】ZooKeeper 工业级的场景(配置中心、日志系统、数据同步系统)

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

深入理解 Hadoop (五)YARN核心工作机制浅析

概述 YARN 的核心设计理念是 服务化&#xff08;Service&#xff09; 和 事件驱动&#xff08;Event EventHandler&#xff09;。服务化 和 事件驱动 软件设计思想的引入&#xff0c;使得 YARN 具有低耦合、高内聚的特点&#xff0c;各个模块只需完成各自功能&#xff0c;而模…

熟悉HDFS常用操作

1. 利用Hadoop提供的Shell命令完成下列任务 (1)向HDFS中上传任意文本文件,如果指定的文件在HDFS中已经存在,由用户指定是追加到原有文件末尾还是覆盖原有的文件。 #检查文件是否存在./bin/hdfs dfs -test -e text.txt echo $? #结果是1 代表已存在 #根据结果判断出文件已存…

dubbo与seata集成

1.seata是什么? Seata 是一款开源的分布式事务解决方案&#xff0c;致力于在微服务架构下提供高性能和简单易用的分布式事务服务。 2.seata的注解 GlobalTransactional&#xff1a;全局事务注解&#xff0c;添加了以后可实现分布式事务的回滚和提交&#xff0c;用法与spring…

VMware虚拟机安装Ubuntu

准备:Ubuntu的镜像文件,VMware,手. 1.新建虚拟机&#xff0c;选择自定义&#xff0c;下一步。 2.硬件兼容性&#xff0c;选择Workstation 16.x&#xff0c;下一步。 3.选择安装程序光盘映像文件&#xff0c;路径为映像文件所在文件夹&#xff0c;下一步。 4. 创建用户和设置密…

hive 函数使用详解

一、前言 在任何一种编程语言中,函数可以说是必不可少的,像mysql、oracle中,提供了很多内置函数,或者通过自定义函数的方式进行定制化使用,而hive作为一门数据分析软件,随着版本的不断更新迭代,也陆续出现了很多函数,以满足日常数据查询与分析的各种场景。 二、hive 函…

GEE中导入研究区shape

找到Assets&#xff0c;新建NEW 等待上传完成 从Assets列表中找到导入文件&#xff0c;复制ID

106短信群发如何发送会员通知

106短信群发可以通过以下步骤发送会员通知&#xff1a; 1.确定通知内容&#xff1a;首先需要确定要发送的通知内容&#xff0c;包括通知的主题、内容、时间、地点等信息。 2.设计通知模板&#xff1a;根据通知内容&#xff0c;设计通知模板。模板应包括短信的格式、语言风格、…

AI教我学编程之C#入门程序详解与拓展

与AI肩并肩 前言一、一个简单的C#程序补充说明对话AI 二、标识符三、关键字四、Main五、空白1. 缩进2. 代码块的间距3. 操作符的空格4. 换行5. 一致性 六、语句七、从程序输出文本主题&#xff1a;从程序中输出文本1. Write 和 WriteLine 方法2. 格式字符串3. 多重标记和值4. 格…