最小生成树,prim算法

Prim算法和Kruskal算法都是用于解决最小生成树问题的经典算法,它们在不同情况下有不同的适用性和特点。

Prim算法:

Prim算法是一种贪心算法,用于构建一个无向图的最小生成树。算法从一个初始节点开始,逐步添加与当前树连接且具有最小权重的边,直到所有节点都被连接。Prim算法的基本思想是从一个起始节点出发,每次选择一个与当前最小生成树相连的节点中,权重最小的边,将这个节点加入最小生成树中,并将其相连的边考虑进来。这样逐步扩展最小生成树,直至所有节点都被包含。

Kruskal算法:

Kruskal算法也是一种贪心算法,用于构建一个无向图的最小生成树。该算法首先将图中的所有边按照权重从小到大进行排序,然后从最小权重边开始,依次将边加入生成树中,但要保证加入边不会形成环。如果加入某条边会导致环的形成,则放弃该边,继续考虑下一条权重较小的边,直到生成树中包含了所有的节点。

区别:

基本思想:Prim算法从一个起始节点开始,逐步添加与当前最小生成树相连的具有最小权重的边。Kruskal算法通过排序边,然后逐个添加边,保证不形成环。

顶点处理:Prim算法在每一步选择中,仅考虑与当前已选择顶点相连的顶点,直接操作顶点Kruskal算法是通过遍历边的方式进行操作,不直接关心顶点。

数据结构:Prim算法通常使用优先队列(最小堆)来维护待选的边,以便每次选择具有最小权重的边。Kruskal算法则通常使用并查集来判断是否会形成环。

性能:在边的数量较少,而顶点的数量较多时,Prim算法通常会更有效。而在边的数量较多,而顶点的数量较少时,Kruskal算法可能更适用。

复杂度:Prim算法的时间复杂度通常在 O(V^2) 到 O(E* log(V)) 之间,取决于实现方式。Kruskal算法的时间复杂度主要由排序边的复杂度决定,通常为 O(E * log(E))。

总的来说,两种算法都能有效地构建最小生成树,但在不同情况下选择合适的算法可以提高效率。

1135. 最低成本联通所有城市

想象一下你是个城市基建规划者,地图上有 n 座城市,它们按以 1 到 n 的次序编号。

给你整数 n 和一个数组 conections,其中 connections[i] = [xi, yi, costi] 表示将城市 xi 和城市 yi 连接所要的costi(连接是双向的)。

返回连接所有城市的最低成本,每对城市之间至少有一条路径。如果无法连接所有 n 个城市,返回 -1

该 最小成本 应该是所用全部连接成本的总和。

在这里插入图片描述
代码实现:

// 定义边
struct Edge{int city;int cost;
};// 定义 边的比较方法
// cost值较小的Edge对象具有更高的优先级,
// 因为EdgeComparator在a的cost大于b的cost时返回true,
// 这意味着在优先级队列中,a应该在b之后。
// 所以,这个优先级队列是一个最小堆(min heap),即队列顶部总是cost最小的Edge对象
struct EdgeComparator{bool operator()(const Edge& a,const Edge& b){return a.cost>b.cost;}
};class Solution {
public:int minimumCost(int n, vector<vector<int>>& connections) {// 连接所有点需要的costint cost = 0;vector<vector<Edge>> edges(n+1);// 定义访问数组vector<bool> visited(n+1,false);//  定义优先队列, cost小的排在前面priority_queue<Edge, vector<Edge>, EdgeComparator> minHeap;visited[1] = true;// 从城市1开始// 建立Edge二维数组// 每个点会对应一个list,每个list中存储:和这个点相连的城市以及到相连城市的距离for(const auto& conn:connections){// 是双向的edges[conn[0]].push_back(Edge{conn[1],conn[2]});edges[conn[1]].push_back(Edge{conn[0],conn[2]});}// 先把和1点相连的Edge进行排序,放入优先队列for(const Edge& edge:edges[1]){minHeap.push(edge);}// 连接点的数量,初始为1int count = 1;while(!minHeap.empty()){Edge e = minHeap.top();minHeap.pop();if(visited[e.city]){// 如果已经访问过某一点了,则直接进入下一次循环continue;}// 如果没有访问过,就设置为truevisited[e.city] = true;// 再把和这个点相连的Edge push进优先队列for(const Edge& edge:edges[e.city]){minHeap.push(edge);}cost += e.cost;// 连接点的数量+1count++;if(count == n){return cost;}}return -1;}
};

1584. 连接所有点的最小费用

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

在这里插入图片描述

完全仿照上面一题的代码,写出了这题的代码,唯二的区别在于,需要自己额外计算一下每个点之间的距离,并且不满足条件时返回0:

// 定义结构体Edge
struct Edge{int city;int cost;
};struct EdgeComparator{bool operator()(const Edge& a,const Edge& b){return a.cost>b.cost;}
};// 计算曼哈顿距离
int compute_Manhattan(vector<vector<int>>& points,int p1,int p2){return abs(points[p1][0]-points[p2][0]) + abs(points[p1][1]-points[p2][1]);
}class Solution {
public:int minCostConnectPoints(vector<vector<int>>& points) {int cost = 0;int n = points.size();// 点的个数vector<vector<Edge>> edges(n);priority_queue<Edge, vector<Edge>, EdgeComparator> minHeap;vector<bool> visited(n,false); // 访问数组visited[0] = true; // 从0点开始searchint count = 1; // 已经访问到了的点(已经相连的点)// 建立了 邻接表for(int i = 0;i<n-1;i++){for(int j = i+1;j<n;j++){// 两点间的曼哈顿距离int distance = compute_Manhattan(points,i,j);edges[i].push_back(Edge{j,distance});edges[j].push_back(Edge{i,distance});}}// 把和0点相关的点push进最小堆for(const Edge& edge:edges[0]){minHeap.push(edge);}while(!minHeap.empty()){Edge e = minHeap.top();minHeap.pop();if(visited[e.city]){// 如果已经访问过该点,则进入下一次循环continue;}visited[e.city] = true; // 标记访问过该点// 再把和该点相连的点push 进 minHeapfor(const Edge& edge:edges[e.city]){minHeap.push(edge);}cost += e.cost; // 加上和这个点相连的costcount++;if(count == n){// 如果n个点都相连了,返回cost即可return cost;}}return 0;}
};

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

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

相关文章

【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【加强管理】《别输在不懂管理上》学习记录,黄金41条

成功有时是很难效法的&#xff0c;但失败是可以避免的&#xff0c;从失败中吸取经验和教训才是管理者的必修课。释义&#xff1a; 图形含义&#x1f332;一级重要&#x1f340;二级重要&#x1f33f;三级主要&#x1f341;存在问题&#x1f33c;解决办法 1 不能从头管到脚 不…

【讨论】视频监控集中存储方案如何做?

视频监控集中存储是指将多个视频监控摄像头所捕捉到的视频信号集中存储于一个中央设备&#xff0c;这个中央设备可以是服务器、网络存储设备或其他专用设备。通过集中存储&#xff0c;可以避免因为存储设备分散而导致的管理不便和难以有效地管理和检索视频数据&#xff0c;同时…

RTT(RT-Thread)ADC设备(RTT保姆级介绍)

目录 ADC设备 前言 ADC相关参数说明 访问ADC设备 配置ADC设备 ADC实例 硬件设计 软件设计 ADC设备 前言 ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换为离散的数字信号的器件。 对于ADC的详细介绍和在STM32中的裸机应用可参考以下…

pandas数据分析38——数据框表格拓展以及缩回对齐

案例背景 需求是这个样的&#xff1a; 把这个表格进行拓展。 代码实现&#xff1a; df pd.DataFrame(np.array([[1, 2, 3,4], [a,b, c,d], [小明,小红, 小马,小天]])) df 方法一&#xff1a;自定义函数&#xff1a; def expand_dataframe(df):m, n df.shapenew_df pd.Dat…

linux系统中设置服务开机自启动

1&#xff1a;背景描述 最近根据工作需要&#xff0c;需要服务实现开机自启动的效果&#xff0c;因为平时只使用过nohup的后台挂起操作&#xff0c;很少接触开机&#xff0c;镜像装机服务自启动的功能&#xff0c;因此&#xff0c;这里简单记录一下。 注意&#xff0c;开机自…

解锁数据潜力:信息抽取、数据增强与UIE的完美融合

解锁数据潜力&#xff1a;信息抽取、数据增强与UIE的完美融合 1.信息抽取&#xff08;Information Extraction&#xff09; 1.1 IE简介 信息抽取是 NLP 任务中非常常见的一种任务&#xff0c;其目的在于从一段自然文本中提取出我们想要的关键信息结构。 举例来讲&#xff0…

从NLP到聊天机器人

一、说明 今天&#xff0c;当打电话给银行或其他公司时&#xff0c;听到电话另一端的机器人向你打招呼是很常见的&#xff1a;“你好&#xff0c;我是你的数字助理。请问你的问题。是的&#xff0c;机器人现在不仅可以说人类语言&#xff0c;还可以用人类语言与用户互动。这是由…

windows权限维持—黄金白银票据隐藏用户远控RustDeskGotoHttp

windows权限维持—黄金白银票据&隐藏用户&远控&RustDesk&GotoHttp 1. 前置1.1. 初始问题1.1.1. 解决办法 2. 隐藏用户2.1. 工具原理2.2. 案例操作2.2.1. 单机添加用户2.2.1.1. 工具添加用户2.2.1.2. 工具查看隐藏用户2.2.1.3. 本地查看隐藏用户 2.2.2. 域内添加…

NeuralNLP-NeuralClassifier的使用记录(二),训练预测自己的【中文文本多分类】

NeuralNLP-NeuralClassifier的使用记录&#xff0c;训练预测自己的【中文文本多分类】 数据准备&#xff1a; ​ 与英文的训练预测一致&#xff0c;都使用相同的数据格式&#xff0c;将数据通过代码处理为JSON格式&#xff0c;以下是我使用的一种&#xff0c;不同的原数据情况…

java+springboot+mysql理发会员管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的理发会员管理系统&#xff0c;系统包含超级管理员&#xff0c;系统管理员、客户、发型师角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;会员管理&#xff1b;发型师管理&#xff1b…

如何保证数据库的数据和Redis的数据一致性

实际项目中有可能会使用Redis缓存数据&#xff0c;那么在更新数据的时候如何保证数据库中的数据和Redis缓存的数据一致&#xff0c;缓存同步策略的选择是一个很重要的问题。网上有各种说法&#xff0c;大概总结有以下几种&#xff0c;看看每种方案是否可行以及存在的问题和适用…

安装软件包

安装软件包 创建一个名为 /home/curtis/ansible/packages.yml 的 playbook : 将 php 和 mariadb 软件包安装到 dev、test 和 prod 主机组中的主机上 将 RPM Development Tools 软件包组安装到 dev 主机组中的主机上 将 dev 主机组中主机上的所有软件包更新为最新版本 vim packa…

关于Firmae缺失binwalk模块

问题 david707:~/FirmAE$ sudo ./run.sh -c weyow ./WAM_9900-20.06.03V.trx [*] ./WAM_9900-20.06.03V.trx emulation start!!! Traceback (most recent call last):File "./sources/extractor/extractor.py", line 19, in <module>import binwalk ModuleNot…

Docker容器:docker基础概述、安装、网络及资源控制

文章目录 一.docker容器概述1.什么是容器2. docker与虚拟机的区别2.1 docker虚拟化产品有哪些及其对比2.2 Docker与虚拟机的区别 3.Docker容器的使用场景4.Docker容器的优点5.Docker 的底层运行原理6.namespace的六项隔离7.Docker核心概念 二.Docker安装 及管理1.安装 Docker1.…

【k8s】基于Prometheus监控Kubernetes集群安装部署

目录 基于Prometheus监控Kubernetes集群安装部署 一、环境准备 二、部署kubernetes集群 三、部署Prometheus监控平台 四、部署Grafana服务 五、grafana web操作 基于Prometheus监控Kubernetes集群安装部署 一、环境准备 IP地址 主机名 组件 192.168.100.131 k8s-ma…

时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测

时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测 目录 时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 时序预测 | MATLAB实现WOA-CNN-GRU鲸鱼算法优化卷积…

基于LVQ神经网络的人脸朝向识别

1案例背景 1.1人脸识别概述 人脸识别作为一个复杂的模式识别问题,近年来受到了广泛的关注,识别领域的各种方法在这个问题上各显所长,而且发展出了许多新方法,大大丰富和拓宽了模式识别的方向。人脸识别、检测,跟踪、特征定位等技术近年来一直是研究的热点。人脸识别是人脸应用…

【制作npm包1】申请npm账号、认识个人包和组织包

概述 在开发当中经常有一种现象&#xff0c;重复代码写了N多遍&#xff0c;再次写同样的逻辑就再次翻查以前的代码逻辑。效率低下且容易出错&#xff0c;封装一个npm包的价值也不仅仅是给别人用&#xff0c;封装一套属于自己或者本部门的npm包也是相当有必要。 也许经常看到一…

RabbitMQ的5种消息队列

RabbitMQ的5种消息队列 1、七种模式介绍与应用场景 1.1 简单模式(Hello World) 一个生产者对应一个消费者&#xff0c;RabbitMQ 相当于一个消息代理&#xff0c;负责将 A 的消息转发给 B。 应用场景&#xff1a;将发送的电子邮件放到消息队列&#xff0c;然后邮件服务在队列…