基础算法篇(3)(蓝桥杯常考点)—图论

前言

这期是基础算法篇的第三节,其中的dijkstra算法更是蓝桥杯中的高频考点

图的基本相关概念

有向图和无向图 自环和重边 稠密图和稀疏图

对于不带权的图,一条路径的路径长度是指该路径上各边权值的总和

对于带权的图,一条路径长度时指该路径上各个边权值得总和

顶点的度是指和它相关联的边的条数,由该顶点发出的边称为顶点的出度,到达该顶点的边称为顶点的入度

无向图中才有联通图和联通分量这些概念

考的时候:有些数据输入格式就是按图给的

(eg:u和v之间有一条长度为k的边)

如果没有说图没有重边和自环,一般默认测试点的图会有重边和自环

有向无环图可以搭配上动态规划用(eg:拓扑+动态规划)(在问最短路有几条时,常要用到动态规划)

图的存储

有两种方式:邻接矩阵和邻接表

1.邻接表的存储方式和树的孩子表示法一样,用vector数组和链式前向星都可以实现

2.邻接矩阵是用一个二维数组,其中edge[i][j]存储顶点i与顶点j之间的边的信息

邻接矩阵:
1.对于带权图而言,若顶点i和顶点j之间有边相连,则邻接矩阵中对应项存放着该边对应的权值若顶点i和顶点j之间不相连,则用无穷大(有时用其他)代表这两顶点间无边
2.对于不带权的图,可以创建一个二维的bool类型的数组,来标记顶点i和j之间有边相连
时间复杂度为:O(n平方),因此适合存稠密图
注意:邻接矩阵如果有重边,一般存其最小值
代码展示:int edges[N][N];//一般需要初始化,vector那个则不用for(int i = 1;i<=m;i++)
{int a,b,c;cin>>a>>b>>c;//a和b之间有一条边,权值为cedges[a][b] = c;//如果是无向边,需要反过来再存一下edges[b][a] = c;}
邻接表:
自己一般喜欢使用vector数组去存
如果存在边权的话,vector数组里面需要放结构体或者pair
pair自己喜欢第一个数据记录边的终点,第二个数据记录边权值
vector数组的下标表示边的起点代码展示:vector<pair<int,int>> edges[N];for(int i=1;i<=m;i++)
{int a,b,c;cin>>a>>b>>c;//a和b之间有一条边,权值为cedges[a].push_back{(b,c)};//如果是无向边,需要反过来再存一下edges[b].push_back{(a,c)};}

图的遍历

图的遍历有DFS和BFS,和树的遍历的实现方法一样

自己常用dfs来搞:
1.邻接矩阵:void dfs(int u)
{cout<<u<<endl;st[u] = true;for(int v =1;v<=n;v++){//如果存在u->v的边,并且没有遍历过if(edges[u][v]!=-1&&st[v])dfs(v);}}main函数里面有memset(edges,-1,sizeof edges);2.vector数组:void dfs(int u){cout<<u<<endl;st[u] = true;for(auto&t:edges[u]){//u->v的一条边,权值为wint v = t.first,w=t.second;if(!st[v]){ dfs[v];}}}

最小生成树

一般用普利姆(Prim)算法和克鲁斯卡尔(Kruskal)算法去构造最小生成树

最小生成树面向的是无向图,如果有向图有无向图返回的性质,也可以用此

Prim算法:
核心:不断加点
步骤:
1.从任意一点开始构造最小生成树(一般选1为起点,dist[1] = 0)
2.将距离该树权值最小且不在树中的顶点,加入到生成树中。(记得判断是否联通)然后更新与该点相连的点到生成树的最短距离(不要忘了考虑重边和自环!)
3.重复2操作n次,直到所有顶点都加入为此Kruskal算法:(运行时间和空间时间允许的话,建议用这个)
核心:不断加边
步骤:
1.所有边按照权值排序
2.每次选出权值最小且两端顶点不连通的一条边,直到所有顶点都联通
时间复杂度:m*logm(m是边数)
这个算法不用图,只用存边,用结构体存即可(也不算邻接表)
定理:最小生成树就是瓶颈生成树
瓶颈生成树:所有生成树中,最大的边权的值最小的那棵树

拓扑排序

拓扑排序的目标是将有向无环图中的所有结点排序

适用于有要完成了前置项才能走的点的图(AOV网)

(eg:一个摄像头能被砸毁的条件是该摄像头所在位置不被其他摄像头监视)

实现方法:
1.将图中所有入度为0的点,加入到队列中

2.取出队头元素,删除与该点相连的边。如果删除之后的后继结点入度变为0,加入到队列中

3.重复2操作,直到图中没有点或者没有入度为0的点为止

需要搞个vectoredges[N]存N的后继

          int in[N]存入度信息

eg: edges[i].push_back(j);//i的后继为j

         in[j]++;//统计入度信息

例题: 洛谷 B3644 【模板】拓扑排序/家谱树

拓扑排序判断是否有环:
跑一遍拓扑排序,如果有结点没有进队,那么表明有环

单源最短路

概念:图中一个顶点到其他各顶点的最短路径

有向图,无向图都能用

常见版dijkstra算法:
流程:
1.创建一个长度为n的dist数组,其中dist[i]表示从起点到i结点的最短路
2.创建一个长度为n的bool数组st,其中st[i]表示i点是否已经确定了最短路
3.初始化:dist[i] = 0,其余结点的dist值为无穷大,表示还没有找到最短路
4.在所有没有确定最短路的点中,找出最短路长度最小的点u。打上确定最短路的标记,然后对u的出边进行松弛操作松弛操作:if(dist[u]+w<dist[v])dist[v] = dist[u]+w;堆优化版的dijkstra算法:
1.创建一个长度为n的dist数组,其中dist[i]表示从起点到i结点的最短路创建一个长度为n的bool数组st,其中st[i]表示i点是否已经确定了最短路创建一个小根堆,维护更新后的结点.(也就是需要确定最短路的结点)
eg:priority_queue<PII,vector<PII>,greater<PII>>heap
2.初始化:dist[i]=0,然后讲{0,s}加到堆里,其余结点的dist值为无穷大,表示还找到最短路
3.弹出堆顶元素,如果该元素已经标记过,就跳过;如果没有,打上标记,进行松弛操作bellman-ford算法(简称BF算法):
核心思想:不断尝试对图上的每一条边进行松弛,直到所有的点都无法松弛为止
1.创建一个长度为n的dist数组,其中dist[i]表示从起点到i结点的最短路
2.初始化:dist[i]=0,其余结点的dist值为无穷大,表示还没有找到最短路
3.每次都对所有的边进行一次松弛操作(一般按结点编号顺序来找边去松弛)
4.重复上述操作,直到所有边都不需要松弛为止
这个算法也不需要存图spfa算法:(本质是用队列对BF算法做优化)
1.创建一个长度为n的dist数组,其中dist[i]表示从起点到i结点的最短路创建一个长度为n的bool数组st,其中st[i]表示i点是否已经在队列中
2.初始化:标记dist[i]=0,同时1入队;其余结点的dist值无穷大,表示还没找到最短路
3.每次拿出队头元素u,去掉在队列中的标记,同时对u所有相连的点v进行松弛操作如果结点v被松弛,那就放进队列中
4.重复上述操作,直到队列中没有结点为止
例题:洛谷  P3385 【模板】负环1.BF判断负环:执行n轮松弛操作,如果第n轮还存在松弛操作,那么就有负环2.spfa算法判断负环:维护一个cnt数组记录从起点到该点所经过的边数,如果cnt[i]>=m,说明有负环
单源路算法总结:(n为结点个数,m为边数)
1.dijkstra算法:时间复杂度:O(n平方)
2.堆优化的dijkstra算法: 时间复杂度:O(m*logm,m为边数)
没有负边权的话用这俩
有负边权就用BF算法和spfa算法
3.BF算法:时间复杂度:nm
4.spfa算法:时间复杂度:km~nm(k要具体题去分析)
5.普通BFS:处理边权全部相同并且非负的单源最短路
6.01BFS:处理边权要么为0,要么为1的单元最短路
问最短路有几条的问题:
例题: 洛谷  P1144 最短路计数
1.这里的松弛操作和上面的有些不同:(要分情况了)dist[u]+w<dist[v]的话:f[v] = f[u]dist[u]+w=dist[v]的话f[v]+=f[u]
2.而且这里的BFS不能用st数组了,其他算法可以
一般做法使用dijkstra算法或者BFS(边权相等才可BFS这个方法)+动态规划

多源最短路

和搜索那里的多源最短路区分(那里是多个起点)

这里是分阶段求最短路(加点求,加点求)–用floyd算法解决

floyd算法适用于任何图,但是不能含负环

floyd算法:其本质是动态规划。其实就是分阶段,逐步更新出我们的最终结果
思路:
1.状态表示:
f[k][i][j]表示:
仅仅经过[1,k]这些点,结点i走到结点j的最短路径的长度
2.状态转移方程:
第一种情况,不选新来的点:f[k][i][j]=f[k-1][i][j]
第二种情况,选择新来的点:f[k][i][j]=f[k-1][i][j]+f[k-1][i][j]
取这两种的min
3.空间优化:可以优化掉第一维
4.初始化:
f[i][i]=0;
f[i][j]为初始状态下i到j的距离,如果没有边则为无穷
5.填表顺序:
一定要先枚举j,再枚举i和j例题: 洛谷  B3647 【模板】Floyd如果题目有限制加点的时机,那就把floyd算法里面的k那一层循环拆了改成判断条件即可
例题: 洛谷  P1119 灾后重建
无向图的最小环问题:
例题:洛谷  P6175 ⽆向图的最⼩环问题
floyd算法循环到k的时候,这个环的最小长度为f[i][j]+e[i][k]+e[k][j]核心部分:
for(int k =1;k<=n;k++)
{//最小环for(int i=1;i<k;i++)for(int j=i=1,j<k,j++)ret = min(ret,f[i][j]+e[i][k]+e[k][j]);//最短距离
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);}

例题的跳转链接汇总

洛谷 B3644 【模板】拓扑排序/家谱树
洛谷 P3385 【模板】负环
洛谷 P1144 最短路计数
洛谷 B3647 【模板】Floyd
洛谷 P1119 灾后重建
洛谷 P6175 ⽆向图的最⼩环问题

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

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

相关文章

Crawl4AI:专为AI设计的开源网页爬虫工具,释放大语言模型的潜能

在当今数据驱动的AI时代,高效获取结构化网页数据是模型训练和应用落地的关键。Crawl4AI作为一款专为大型语言模型(LLMs)设计的开源爬虫工具,凭借其极速性能、AI友好输出和模块化设计,正在成为开发者社区的热门选择。本文将深入解析其核心特性与技术优势。 一、Crawl4AI的核…

前后端数据序列化:从数组到字符串的旅程(附优化指南)

&#x1f310; 前后端数据序列化&#xff1a;从数组到字符串的旅程&#xff08;附优化指南&#xff09; &#x1f4dc; 背景&#xff1a;为何需要序列化&#xff1f; 在前后端分离架构中&#xff0c;复杂数据类型&#xff08;如数组、对象&#xff09;的传输常需序列化为字符…

汇编学习之《移位指令》

这章节学习前需要回顾之前的标志寄存器的内容&#xff1a; 汇编学习之《标志寄存器》 算数移位指令 SAL (Shift Arithmetic Left)算数移位指令 : 左移一次&#xff0c;最低位用0补位&#xff0c;最高位放入EFL标志寄存器的CF位&#xff08;进位标志&#xff09; OllyDbg查看…

NLP高频面试题(二十九)——大模型解码常见参数解析

在大语言模型的实际应用中&#xff0c;如何更有效地控制文本生成的质量与多样性&#xff0c;一直是热门研究话题。其中&#xff0c;模型解码&#xff08;decode&#xff09;策略至关重要&#xff0c;涉及的主要参数包括 top_k、top_p 和 temperature 等。本文将详细介绍这些常见…

【C#】Task 线程停止

CancellationTokenSource cts 是用于控制任务&#xff08;线程&#xff09;停止运行的。我们一步步来解释它的作用。 &#x1f50d; 现在的代码结构大概是这样的&#xff1a; Task.Run(() > {while (true){// 不断循环采集图像} });这种写法虽然简单&#xff0c;但最大的问…

WebRTC的ICE之TURN协议的交互流程中继转发Relay媒体数据的turnserver的测试

WebRTC的ICE之TURN协议的交互流程和中继转发Relay媒体数据的turnserver的测试 WebRTC的ICE之TURN协议的交互流程中继转发Relay媒体数据的turnserver的测试 WebRTC的ICE之TURN协议的交互流程和中继转发Relay媒体数据的turnserver的测试前言一、TURN协议1、连接Turn Server 流程①…

Redis + Caffeine多级缓存电商场景深度解析

Redis Caffeine多级缓存 Redis Caffeine多级缓存电商场景深度解析一、实施目的二、具体实施2.1 架构设计2.2 组件配置2.3 核心代码实现 三、实施效果3.1 性能指标对比3.2 业务指标改善3.3 系统稳定性 四、关键策略4.1 缓存预热4.2 一致性保障4.3 监控配置Prometheus监控指标 …

前端开发3D-基于three.js

基于 three.js 渲染任何画面&#xff0c;都要基于这 3 个要素来实现 1场景scene&#xff1a;放置物体的容器 2摄像机&#xff1a;类似人眼&#xff0c;可调整位置&#xff0c;角度等信息&#xff0c;展示不同画面 3渲染器&#xff1a;接收场景和摄像机对象&#xff0c;计算在浏…

代码随想录算法训练营--打卡day4

一.移除链表元素 1.题目链接 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 2.思路 通过 while 循环来遍历链表&#xff0c;只要 cur 的下一个节点不为空&#xff0c;就继续循环。在循环中&#xff0c;对 cur 的下一个节点的值进行判断&#xff1a; 值不等于…

虚拟电厂:多元能源聚合,开启绿色电力新时代

虚拟电厂&#xff1a;多元能源聚合&#xff0c;开启绿色电力新时代 在“双碳”目标驱动下&#xff0c;电力系统正经历从集中式向分布式、从单一能源向多能互补的深刻变革。 作为能源互联网的核心载体&#xff0c;虚拟电厂通过数字化技术整合多种能源资源&#xff0c;而是像指…

高通Android10 铃声通话音频80%音量修改

先修改最高的音量step --- a/SC60_AP/frameworks/base/services/core/java/com/android/server/audio/AudioService.javab/SC60_AP/frameworks/base/services/core/java/com/android/server/audio/AudioService.java-311,14 311,14 public class AudioService extends IAudio…

类加载过程?类隔离了解过吗?

类加载过程详解 类加载是 JVM 将类的字节码从磁盘、网络或其他来源加载到内存&#xff0c;并转换为 Class 对象的过程&#xff0c;主要分为以下 五个阶段&#xff1a; 1. 加载&#xff08;Loading&#xff09; 任务&#xff1a;查找类的二进制字节流&#xff08;如 .class 文…

使用msmtp和mutt在CentOS上发送指定目录下的所有文件作为邮件附件

1.安装 msmtp&#xff1a; 如果尚未安装&#xff0c;请先通过以下命令安装msmtp。 sudo yum install msmtp 2.配置 msmtp 使用新浪邮箱&#xff1a; 创建或编辑配置文件~/.msmtprc&#xff0c;输入以下内容&#xff08;记得替换授权码&#xff09;。 defaults tls on tls_st…

Vue+Elementui首页看板

源码 <template><!-- 查询条件--><div class="optimize-norm" v-loading="selectDataLoading"><el-form :model="queryParams" ref="queryRef" style="padding-bottom:8px" :inline="true"…

汇编学习之《指针寄存器大小端学习》

什么是指针寄存器&#xff1f; 操作栈的寄存器 栈&#xff1a; 保存函数里面传递的参数&#xff0c;局部变量等。 EBP&#xff1a; 指向栈底的指针 ESP&#xff1a; 指向栈顶的指针。 计算入栈地址变化规则 通过OllDbg查看 有可能点击安装的时候栈区域第一次查看会没有显…

Oracle数据库数据编程SQL<3.7 PL/SQL 触发器(Trigger)>

触发器是Oracle数据库中的一种特殊存储过程&#xff0c;它会在特定数据库事件发生时自动执行。触发器通常用于实现复杂的业务规则、数据验证、审计跟踪等功能。 目录 一、触发器基本概念 1. 触发器特点 2. 触发器组成要素 二、触发器类型 1. DML触发器 2. DDL触发器 3.…

2025年渗透测试面试题总结-某 携程旅游-基础安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 携程旅游-基础安全工程师 反序列化原理 核心原理 扩展分析 SQL注入本质 核心原理 扩展分析 SQL注…

CSS 边框(Border)样式详解

CSS 边框&#xff08;Border&#xff09;样式详解 CSS 提供了多种边框样式&#xff0c;使我们能够控制元素的外观。本文将详细介绍 CSS 边框的各种属性及应用示例。 1. 基本边框属性 CSS 主要使用 border 相关属性定义边框&#xff0c;基本语法如下&#xff1a; border: [边…

SpringCould微服务架构之Docker(6)

容器的基本命令&#xff1a; 1. docker exec &#xff1a;进入容器执行命令 2. docker logs: -f 持续查看容器的运行日志 3. docker ps&#xff1a;查看所有运行的容器和状态 案例&#xff1a;创建运行一个容Nginx容器 docker run--name myNginx -p 80:80 -d nginx 命…

unity3d端监听 uri scheme

一、消息监听 1.创建一个脚本命名为 “URISchemeListener” &#xff0c;用于接收URI消息&#xff08;代码如下&#xff09;。 using System; using System.Runtime.InteropServices; using UnityEngine; using UnityEngine.UI;public class URISchemeListener : MonoBehavio…