当前位置: 首页 > news >正文

数据结构与算法-图论-最短路和其他的结合

介绍

最短路算法常与深度优先搜索(DFS)、动态规划(DP)、二分答案、拓扑排序等算法结合使用:

- 最短路与DFS结合:在一些图的路径问题中,当需要访问特定的多个结点,且数据范围较小时,可使用DFS。例如在一个有(n)个结点、(m)条无向边的图中,有(x)个结点必须访问,求最短路径。此时问题可转化为如何排列这(x)个结点,使得从起始结点依次经过其余结点所经过的路径最短。由于DFS时间复杂度较高,一般先用Dijkstra算法对这(x)个结点间的最短路做预处理,然后用DFS进行结点排列尝试,时间复杂度约为(O(ntimes ntimeslog(m)))。

- 最短路与DP结合:在涉及路径选择和最优值求解,且问题具有最优子结构性质时,会结合DP。比如在一个图中,从起点到终点的过程中,在不同的结点有不同的花费或收益,同时路径存在一定的限制条件,要求找到能获取最大收益或最小花费的路径。可以用DP来记录每个状态(到达某个结点的情况)下的最优值,用最短路算法来确定路径的可达性和距离信息,二者相互配合求解。

- 最短路与二分答案结合:当问题是求解使得某一条件满足的最优值(如路径中第(k)大的边最小)时,且该最优值存在二段性(即大于该值的情况和小于该值的情况有明显区分),可以使用二分答案的方法。通过二分枚举可能的最优值,然后利用最短路算法来判断在该值下是否满足题目条件(如查找该路径中有多少条边的权重大于枚举值),从而逐步缩小范围找到最优解。

- 最短路与拓扑排序结合:在处理有向无环图(DAG)且存在边权(可正可负)的最短路问题时,常结合拓扑排序。例如有多块区域通过道路(边权大于(0))和航线(边权可正可负,单向)相连,求最短路。由于存在负权边,不能直接用Dijkstra算法。此时先对区域间的道路用Dijkstra算法处理,对于航线,利用拓扑排序得到拓扑序,根据该顺序计算各个区域间的最短路,这样能有效处理负权边和有向图的情况。

新年好(dfs+最短路)

分析:


这道题可以结合深度优先搜索(DFS)和 SPFA(Shortest Path Faster Algorithm)算法来求解,以下是具体分析:

算法思路

图的存储:使用邻接表来存储图的结构,对于每个车站(节点),记录与其相连的车站以及通过公路所需的时间(边的权重)。

SPFA 求单源最短路径:从车站 1 出发,利用 SPFA 算法计算到车站 a, b, c, d, e 的最短路径。SPFA 算法基于队列实现,不断更新到各个节点的最短距离。初始时,将起点的距离设为 0,其他节点设为无穷大。每次从队列中取出一个节点,更新其相邻节点的距离,如果某个节点的距离被更新且该节点不在队列中,则将其加入队列。重复此过程,直到队列为空。

DFS 进行路径搜索:在得到从车站 1 到各个亲戚所在车站的最短距离后,使用 DFS 来枚举所有可能的拜访顺序。从车站 1 出发,依次选择一个未访问过的亲戚所在车站进行访问,记录路径长度,当访问完所有亲戚所在车站后,再返回车站 1,计算总路径长度。通过比较所有可能路径的总长度,找出最短的那一条。

伪代码:

2:通信线路(二分+最短路):

分析:


这道题可以通过二分答案和最短路算法来求解,以下是详细分析:

算法思路

1. 二分答案:由于要找的是完成升级的最少花费,而这个花费是路径上剩余电缆中最贵的那条的价格,所以可以对这个价格进行二分。价格的范围是从 (1) 到所有电缆升级花费中的最大值 (L_{max})。每次二分一个价格 (mid),判断是否存在一条从 (1) 号基站到 (N) 号基站的路径,在这条路径上不超过 (K) 条电缆的花费大于 (mid)。如果存在这样的路径,说明可以尝试更小的价格;如果不存在,则需要增大价格。

2. 判断路径是否存在(最短路算法):在二分过程中,对于每个假设的价格 (mid),需要判断是否存在满足条件的路径。这里可以使用最短路算法(如迪杰斯特拉算法或SPFA算法)进行改造。将花费大于 (mid) 的电缆看作权重为 (1)(表示这条电缆是需要额外付费考虑的),花费小于等于 (mid) 的电缆看作权重为 (0)。然后求从 (1) 号基站到 (N) 号基站的最短路,如果最短路的权重小于等于 (K),则说明存在满足条件的路径。

伪代码:

3-道路与航线(拓扑排序+最短路):

分析:


一种很巧妙的解题思路,利用连通块、拓扑排序和迪杰斯特拉算法结合来求解从发送中心城镇 (S) 到每个城镇的最便宜方案

算法思路

1. 划分连通块: - 仅考虑道路(因为道路是无向且可构成连通区域),使用深度优先搜索(DFS)或并查集算法来标记每个城镇所属的连通块。通过遍历所有道路,将相互连通的城镇划分到同一个连通块中,这样可以把整个图按道路连通性划分为若干个连通块。 - 记录每个连 通块包含的城镇节点。

2. 构建连通块之间的拓扑图: - 考虑航线,对于每条航线 ( (u, v) ) ,找到 (u) 和 (v) 所属的连通块 (block_u) 和 (block_v) 。如果 (block_u neq block_v) ,则在连通块之间构建一条有向边 ( (block_u, block_v) ) ,并记录这条边对应的航线信息(如花费等)。同时,记录每个连通块的入度(即指向该连通块的有向边数量)。 - 由于题目条件保证航线构成的图无环,所以这些连通块之间的有向边也构成一个有向无环图(DAG)。

3. 拓扑排序与迪杰斯特拉结合: - 把入度为 (0) 的连通块入队,开始拓扑排序。 - 对于每个连通块,先在其内部使用迪杰斯特拉算法,计算该连通块内从属于该连通块且是发送中心城镇 (S) 所在的节点(如果 (S) 在该连通块内)到其他节点的最短路径。 - 当处理一个连通块时,检查从该连通块出发的航线(即连通块之间的有向边),对于每条航线对应的目标连通块,如果目标连通块的入度减为 (0) ,则将其入队。同时,根据航线的花费,更新目标连通块内节点的最短距离(如果通过这条航线能使距离更短)。 - 重复上述步骤,直到队列为空,此时得到的就是从 (S) 到各个城镇的最短距离。

伪代码:

4最优贸易:

分析:

这种利用跑正反两次 SPFA 算法的思路是很巧妙的,下面详细分析其原理、实现步骤以及复杂度:

思路原理:

正向 SPFA:从 1 号城市出发,使用 SPFA 算法遍历所有能到达的城市。在遍历过程中,记录从 1 号城市到每个城市 k 路径上经过的所有城市中水晶球价格的最小值,存放在 dmin[k] 中。这样就能得到从起点 1 号城市到各个可达城市路径上的最低买入价格。

反向 SPFA:将图中的边方向全部反向(或者在实现时以相反的逻辑处理),从 n 号城市出发再次使用 SPFA 算法。这次记录从 n 号城市到每个城市 k 路径上经过的所有城市中水晶球价格的最大值,存放在 dmax[k] 中 。也就是得到了从各个城市到终点 n 号城市路径上的最高卖出价格。

计算结果:通过遍历所有城市 k,计算 dmax[k] - dmin[k],取其中的最大值就是在从 1 号城市出发到 n 号城市的过程中,进行最多一次买卖水晶球能赚取的最大旅费。如果所有的差值都小于等于 0,则表示赚不到差价。

伪代码:

相关文章:

  • 学睿德毅AI 赋能教育拓展短视频创作边界
  • 基于Electron的应用程序安全测试基础 — 提取和分析.asar文件的案例研究
  • 【tplink】校园网接路由器如何单独登录自己的账号,wan-lan和lan-lan区别
  • 深入xtquant:Python量化交易的桥梁与核心
  • 网络安全虚拟化组成
  • 散户情绪周期模型(情绪影响操作)
  • 16.1 LangChain 表达式语言(LCEL)深度解析:构建灵活高效的大模型应用流水线
  • Nginx处理http的流程
  • 【AI+智造】基于SKF IMAX-16+PT1000与Odoo18工业物联网架构智慧生产诊断系统集成方案
  • Prompt Engineering for Large Language Models
  • 软件工程:软件需求之需求编写规则
  • 【六祎 - Note】Redis缓存设计模型,备忘录;
  • WPF-ReactiveUi
  • .bash_profile一些笔记
  • 在kubernetes集群中持续压测 SpringCloud 应用,pod 的 memory cache 持续增长问题
  • Android系统的“层次”结构
  • Lucene硬核解析专题系列(一):Lucene入门与核心概念
  • LeetCode 热题 100_有效的括号(69_20_简单_C++)(栈;栈+哈希表(建立左右括号的对应关系))
  • [密码学实战]Java实现国密(SM2)密钥协商详解:原理、代码与实践
  • 解决yarn run dev报错: TypeError: Cannot create property ‘-registry-npmmirror-com‘
  • 二级网站建设标准/网络推广策划方案
  • 我们的网站正在建设之中/附近电脑培训班零基础
  • 东莞企业网站制/搜索优化的培训免费咨询
  • 深圳信科网站建设/网站seo基本流程
  • 顺德网站建设7starry/成品网站货源1
  • 长沙正规企业网站制作平台/搜索引擎营销的模式有哪些