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

一.应用的场景

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

二.最小生成树的定义

生成树:
图的生成树是它的一颗含有其所有顶点无环连通子图。
【简单说就是所有顶点连接在一起,并且没有环。
因此有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.hqwc.cn/news/338666.html

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

相关文章

全志T113开发板Qt远程调试

1引言 通常情况下工程师在调试Qt程序时&#xff0c;需要频繁制作镜像烧录到核心板来测试Qt程序是否完善&#xff0c;这样的操作既费时又费力。这时我们可以通过QtCreator设备功能&#xff0c;定义设备后&#xff0c;在x86_64虚拟机上交叉编译qt程序&#xff0c;将程序远程部署到…

UE5 UE4 修复GPU驱动程序崩溃

原贴链接&#xff1a;https://mp.weixin.qq.com/s/e5l9XtfwEFWgwhHi1b2idg UE5 UE4在处理含有大量图形的项目时&#xff0c;你有可能会遇到GPU崩溃 可以通过修改注册表&#xff0c;修复崩溃。 GPU崩溃情况概述 UE5 UE4在处理含有大量图形的项目时&#xff0c;你有可能会遇到G…

websocket介绍并模拟股票数据推流

Websockt概念 Websockt是一种网络通信协议&#xff0c;允许客户端和服务器双向通信。最大的特点就是允许服务器主动推送数据给客户端&#xff0c;比如股票数据在客户端实时更新&#xff0c;就能利用websocket。 Websockt和http协议一样&#xff0c;并不是设置在linux内核中&a…

宏景eHR fileDownLoad SQL注入漏洞复现

0x01 产品简介 宏景eHR人力资源管理软件是一款人力资源管理与数字化应用相融合,满足动态化、协同化、流程化、战略化需求的软件。 0x02 漏洞概述 宏景eHR fileDownLoad 接口处存在SQL注入漏洞,未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令,从而窃取数据库敏感…

Apache ActiveMQ RCE CNVD-2023-69477 CVE-2023-46604

漏洞简介 Apache ActiveMQ官方发布新版本&#xff0c;修复了一个远程代码执行漏洞&#xff0c;攻击者可构造恶意请求通过Apache ActiveMQ的61616端口发送恶意数据导致远程代码执行&#xff0c;从而完全控制Apache ActiveMQ服务器。 影响版本 Apache ActiveMQ 5.18.0 before …

深入理解 Flink(四)Flink Time+WaterMark+Window 深入分析

Flink Window 常见需求背景 需求描述 每隔 5 秒&#xff0c;计算最近 10 秒单词出现的次数 —— 滑动窗口 每隔 5 秒&#xff0c;计算最近 5 秒单词出现的次数 —— 滚动窗口 关于 Flink time 种类 TimeCharacteristic ProcessingTimeIngestionTimeEventTime WindowAssign…

uniapp 字母索引列表插件(组件版) Ba-SortList

简介&#xff08;下载地址&#xff09; Ba-SortList 是一款字母索引列表组件版插件&#xff0c;可自定义样式&#xff0c;支持首字母字母检索、首字检索、搜索等等&#xff1b;支持点击事件。 支持首字母字母检索支持首字检索支持搜索支持点击事件支持长按事件支持在uniapp界…

20240110从官网下载7-zip

20240110从官网下载7-zip 2024/1/10 15:17 百度搜索&#xff1a;7-zip 官网 https://sparanoid.com/lab/7z/ 欢迎来到 7-Zip 官方中文网站&#xff01; 7-Zip 是一款拥有极高压缩比的开源压缩软件。 下载 7-Zip 23.01 稳定版适用于 Windows 操作系统&#xff08;2023-06-30&a…

6.1.2捕捉图像(3)

6&#xff0e;文字捕捉 除了可以捕捉图像外&#xff0c;HyperSnap6还有一个非常神奇、非常实用的功能——文字捕捉。利用文字捕捉&#xff0c;可以把一段不可复制的文字捕捉下来&#xff0c;以便于重新编辑。 (1)右单击桌面上的“我的电脑”&#xff0c;在弹出的快捷菜单中选…

TS 36.321 V12.0.0-MAC过程

​本文的内容主要涉及TS 36.321&#xff0c;版本是C00&#xff0c;也就是V12.0.0。

Flink中的状态管理

一.Flink中的状态 1.1 概述 在Flink中&#xff0c;算子任务可以分为有状态和无状态两种状态。 无状态的算子任务只需要观察每个独立事件&#xff0c;根据当前输入的数据直接转换输出结果。例如Map、Filter、FlatMap都是属于无状态算子。 而有状态的算子任务&#xff0c;就…

labelstudio镜像构建提示 Problem executing scripts APT::Update::Post-Invoke ‘rm

构建镜像真难&#xff0c;害惨了我。报如下的错误&#xff1a; #12 54.36 E: Problem executing scripts APT::Update::Post-Invoke rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true #12 54.36 E: Sub-process retur…