【第二十三课】最小生成树:prime 和 kruskal 算法(acwing858,859 / c++代码 )

目录

前言

Prime算法--加点法

acwing-858 

代码如下

一些解释 

Kruskal算法--加边法

acwing-859

并查集与克鲁斯卡尔求最小生成树 

代码如下

一些解释  


前言

之前学最短路的时候,我们都是以有向图为基础的,当时我们提到如果是无向图,只要记得两个顶点处都要加边就好了。

而在最小生成树的问题中,我们所面临的大多都是无向图。

这个姐姐👇对这两种算法的讲解非常清晰,没有代码部分,但是对于理解这两种算法的做法很有帮助,推荐看一下。 

【数据结构 图 最小生成树 Prime和Kruskal算法】

截取自视频。

感觉总结的很好,就搬过来啦(侵删) 

Prime算法--加点法

prime算法也叫加点法,主要是通过不断将所有顶点都加入到生成树中实现的。

利用该算法求最小生成树的步骤就是:

从任意1个顶点开始,在其他所有顶点中,选出一个离它距离最近的顶点,将其与该顶点进行连线;之后我们看其他的顶点中   离这两个已经选中的点  之间的距离最短的点,再将其连线......

由此我们可以总结出,我们要看的是:其他顶点中 到已经选出的这些顶点的集合 距离最短的点,我们把这个集合称为生成树,这里可以理解哈。

因此我们可以判断dist数组的含义应该是:存储每一个顶点到 集合(也就是生成树) 的最短距离。

prime算法的代码和dijkstra算法的实现是差不多的,主要区别就是dist数组的含义。前者是找离这个集合最短距离的点,后者找的是离某个源点距离最短的点

下面这个图模拟我们prime算法的手算的步骤

方便大家理解啦~ 

prime算法时间复杂度是O(n^2),适用于解决稠密图的问题。 

下面是模板题:

acwing-858 

可以看出数据范围边数远大于点数,属于稠密图。

与dijkstra算法的思路是差不多的,直接看代码把 

代码如下

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=510, INF=0x3f3f3f3f;
int n,m;
int g[N][N];
int dist[N];//存储每一个顶点到 集合(也就是生成树) 的最短距离
bool st[N];
int prime()
{memset(dist,0x3f,sizeof dist);int ans=0;for(int i=0;i<n;i++)//要加入所有的顶点,因此要循环n次{int t=-1;for(int j=1;j<=n;j++){if(!st[j] && (t==-1 || dist[t]>dist[j])){t=j;}}if(i && dist[t]==INF)return INF;if(i)ans+=dist[t];//第一个顶点权值是0,没必要再加一次,因此存在该if语句//选中t之后,比较原来的各个顶点到生成树的距离 与 各顶点与t顶点的权值的大小关系for(int j=1;j<=n;j++){dist[j]=min(dist[j],g[t][j]);}st[t]=1;}return ans;
}
int main()
{cin>>n>>m;memset(g,0x3f,sizeof g);for(int i=0;i<m;i++){int a,b,c;cin>>a>>b>>c;g[a][b]=g[b][a]=min(g[a][b],c);}int t=prime();if(t==INF)puts("impossible");else cout<<t<<endl;return 0;
}

一些解释 

1.if(i && dist[t]==INF)return INF; 

这里我们判断除了第一个顶点之外的其他顶点,到生成树的距离是否是无穷大,如果是无穷大说明图不连通,无法构成生成树

由于我们外层循环只控制循环次数,表示要加入n个顶点,且i从0开始,说明了第一个顶点是作为第0次循环实现的,因此这里排除第一个顶点,直接判断 i 就可以

为什么要跳过第一个顶点?

如果我们不跳过第一个顶点,那么在第一次循环时,由于所有顶点到生成树的距离都被初始化为无穷大,所以会直接返回无穷大,这显然是不正确的。因此,我们需要在第一次循环时跳过这个检查。

2.dist[j]=min(dist[j],g[t][j]); 

这里遍历各个顶点,判断 其原始的dist[j]与添加了 t 顶点之后,t与j顶点之间的权值 的大小关系,从而更新出每个顶点到生成树的距离。(因为既然t已经被加入到生成树中,那么到t的权值也就是到生成树的距离啦。)

把prime与dijkstra的代码放在一起对比一下

Kruskal算法--加边法

kruskal算法与prime对应是加边法,主要通过不断加边,连接到所有顶点之后就得到了最小生成树。

利用这种方法求最小生成树的步骤是:

在所有的边中不断的找最小的边加入到我们最小生成树的集合中,直到将所有顶点都连入。在加边过程中,避免成环即可。

曾经学数据结构的时候,手算我还是比较喜欢用克鲁斯卡尔算法的哈哈哈,感觉加边理解上好像更简单一点。

acwing-859

并查集与克鲁斯卡尔求最小生成树 

我们记得在并查集算法中,进行两个集合的合并和查找操作,就是利用树型结构实现的,在克鲁斯卡尔算法求最小生成树时,我们最终就是将顶点都连在一起算是得到了最小生成树,因此我们可以想着利用并查集的思想来实现克鲁斯卡尔求最小生成树。

嗯,,可以想一下二者的联系。我通过这样可以理解二者的关联。

下面是gpt的解释,更全面和专业一点hh,可以看看帮助理解一下~

应该是可以理解啦。 

需要的话可以回顾一下并查集的知识,之前写过哒

【第十四课】并查集(acwing-837连通块中点的数量 / c++代码 / 思路详解) 

代码如下

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+10;
int n,m;
int p[N];
struct Edge{int a,b,w;//运算符重载函数bool operator< (const Edge &W)const{return w<W.w;}
}edges[N];
int find(int x)
{if(p[x]!=x)p[x]=find(p[x]);return p[x];
}
int main()
{cin>>n>>m;for(int i=0;i<m;i++){int a,b,w;cin>>a>>b>>w;edges[i]={a,b,w};}sort(edges,edges+m);//每个顶点都单独处在一个集合里for(int i=1;i<=n;i++)p[i]=i;int res=0,count=0;//res累加权值 count存储加入的边数for(int i=0;i<=m;i++)//遍历排好序的边的信息{int a=edges[i].a,b=edges[i].b,w=edges[i].w;a=find(a),b=find(b);//如果该边的两个顶点不连通 说明不会形成环if(a!=b){p[a]=b;res+=w;count++;}}if(count<n-1)puts("impossible");//如果边数并不符合 说明不存在最小生成树else cout<<res;return 0;
}

一些解释  

sort(edges,edges+m);

这里我们调用sort函数,直接写的edge结构体-edge+m,就是因为在结构体中我们定义了重载

//运算符重载函数bool operator< (const Edge &W)const{return w<W.w;}

因为结构体中含有多个变量,如果不定义运算符重载,那么在使用 sort 函数等需要比较边的权值大小的地方,编译器将无法确定如何比较两个 Edge 对象 。

关于重载的一些知识,,,


今年就先写到这里啦。大家除夕快乐啦~

有问题欢迎指出,一起加油!!

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

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

相关文章

Java基础深度剖析:从数据类型到新特性一揽无余

Java基础深度剖析&#xff1a;从数据类型到新特性一揽无余 Java 基础一、数据类型基本类型包装类型缓存池 二、String概览不可变的好处String, StringBuffer and StringBuilderString Poolnew String("abc") 三、运算参数传递float 与 double隐式类型转换switch 四、…

百度PaddleOCR字符识别推理部署(C++)

1 环境 1.opencv&#xff08;https://sourceforge.net/projects/opencvlibrary/&#xff09; 2.cmake&#xff08;https://cmake.org/download/&#xff09; 3.vs2019&#xff08;(https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1) 4.paddleOCR项目-建议2.0(http…

数据结构第十四天(树的存储/双亲表示法)

目录 前言 概述 接口&#xff1a; 源码&#xff1a; 测试函数&#xff1a; 运行结果&#xff1a; 往期精彩内容 前言 孩子&#xff0c;一定要记得你的父母啊&#xff01;&#xff01;&#xff01; 哈哈&#xff0c;今天开始学习树结构中的双亲表示法&#xff0c;让孩…

Nginx实战:1-安装搭建

目录 前言 一、yum安装 二、编译安装 1.下载安装包 2.解压 3.生成makefile文件 4.编译 5.安装执行 6.执行命令软连接 7.Nginx命令 前言 nginx的安装有两种方式&#xff1a; 1、yum安装&#xff1a;安装快速&#xff0c;但是无法在安装的时候带上想要的第三方包 2、…

第二十七回 武松威镇安平寨 施恩义夺快活林-人人爱用的Python编程语言

张青提议武松不要去牢城营受苦&#xff0c;可以把公差杀掉然后去二龙山入伙鲁智深。武松却坚持他的道义原则&#xff0c;不愿意伤害一路上照顾他的两位公人。张青尊重他的决定&#xff0c;救醒了两位公人。 张青、孙二娘和武松以及两位公人一起喝酒吃饭&#xff0c;张青还向武…

大数据Flume--入门

文章目录 FlumeFlume 定义Flume 基础架构AgentSourceSinkChannelEvent Flume 安装部署安装地址安装部署 Flume 入门案例监控端口数据官方案例实时监控单个追加文件实时监控目录下多个新文件实时监控目录下的多个追加文件 Flume Flume 定义 Flume 是 Cloudera 提供的一个高可用…

幻兽帕鲁服务器怎么更新?进入游戏显示:加入的比赛正在运行不兼容的版本,请尝试升级游戏版本(阿里云)

幻兽帕鲁服务器怎么更新&#xff1f;进入游戏显示&#xff1a;加入的比赛正在运行不兼容的版本&#xff0c;请尝试升级游戏版本。这是因为游戏客户端或者服务器上的游戏服务端&#xff0c;没有更新版本。导致两个版本不一致&#xff0c;所以无法进入游戏。 最近幻兽帕鲁 官方客…

15.3 Redis入门(❤❤❤❤)

15.3 Redis入门❤❤❤❤ 1. redis简介与配置1.1 简介1.2 Windows安装1.3 Linux安装1.4 守护进程方式启动1.5 客户端启动与使用1.6 指定生成日志 2. 使用2.1 客户端redis使用命令2.2 redis存储的数据类型1. String字符串类型2. Hash键值类型3. List列表类型4. Set与Zset集合类型…

问题:超声波纵波斜入射时,当入射角大于第一临界角小于第二临界角时,在第二介质内只有折射横波。 #微信#经验分享#其他

问题&#xff1a;超声波纵波斜入射时&#xff0c;当入射角大于第一临界角小于第二临界角时&#xff0c;在第二介质内只有折射横波。 参考答案如图所示

面向对象编程:理解其核心概念与应用

引言 在编程的世界中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;已成为一种主流的编程范式。它提供了一种组织和管理代码的有效方式&#xff0c;使得代码更加模块化、可重用和易于维护。本文将带您深入探讨面向对象编程的核心概念及其…

波奇学Linux:文件重定向和虚拟文件系统

重定向 文件描述符所对应的分配规则&#xff0c;从0开始&#xff0c;寻找最小没有使用的数组位置。 如图所示&#xff0c;关闭文件描述符的0&#xff0c;新打开的文件描述符为0&#xff0c;而关闭2&#xff0c;文件描述符为2。 重定向&#xff1a;文件输出的对象发生改变 例…

网络协议、网络传输认识

目录 网络协议概念 网络协议具象化理解 协议分层 TCP/IP模型 网络传输基本流程 网络协议概念 网络协议是计算机网络中用于在通信设备之间传输数据的规则集合。这些规则定义了数据的格式、传输方式、错误检测和纠正方法等&#xff0c;以确保不同设备之间的通信能够正确进行…

计算机网络之一

目录 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网 1.2.因特网发展的三个阶段 1.3基于ISP的三层架构的因特网 1.4.因特网的组成 2.三种交换方式 2.1电路交换 2.2分组交换 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网…

Qualcomm 蓝牙耳机 FAQ(41)---------Audio 问题分析之 ACAT Tools安装

大家好&#xff01; 新的一年&#xff0c;在此祝大家&#xff1a;新年快乐&#xff01;工作上步步高升&#xff01;&#xff01;龙年大吉&#xff01;&#xff01;&#xff01; 也欢迎大家登录大大通平台&#xff0c;春节期间正常更新文章&#xff0c;期待你的到来&#xff0…

Docker-现代化应用部署的利器

一、容器部署的发展 今天我们来说说容器部署。我们知道容器部署的发展大致分三个阶段&#xff0c;下面来介绍一下不同阶段的部署方式的优缺点 物理机部署 优点是可以提供更高的性能、资源控制&#xff0c;也可以提供更好的数据隔离和安全性&#xff0c;因为不同的应用程序运行在…

(十八)springboot实战——spring securtity注解方式的授权流程源码解析

前言 在上一节内容中&#xff0c;我们介绍了如何在FilterSecurityInterceptor过滤器中处理用户的授权流程&#xff0c;并分析了其源码&#xff0c;spring security还提供了方法级别的授权方式&#xff0c;通过EnableMethodSecurity注解启用权限认证流程&#xff0c;只需要在方…

回归预测模型:MATLAB多项式回归

1. 多项式回归模型的基本原理 多项式回归是线性回归的一种扩展&#xff0c;用于分析自变量 X X X与因变量 Y Y Y之间的非线性关系。与简单的线性回归模型不同&#xff0c;多项式回归模型通过引入自变量的高次项来增加模型的复杂度&#xff0c;从而能够拟合数据中的非线性模式。…

【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

飞天使-linux操作的一些技巧与知识点8-zabbix6.0 容器搭建

文章目录 安装docker安装步骤mysql下载镜像安装zabbix 使用zabbix非host模式创建 测试效果 安装docker 1. 配置官方 yum 源$ sudo yum install -y yum-utils $ sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo2. 安装 Docker$ …

【02】右旋函数(C语言)

目录 题目&#xff1a;给定一个整数数组nums&#xff0c;将数组中的元素向右轮转k个位置&#xff0c;其中k是非负数。 1.暴力求解&#xff08;轮转k次) 2. 三段逆置求解 ①逆置函数 ②轮转函数 3.空间换时间求解 题目&#xff1a;给定一个整数数组nums&#xff0c;将数组中…