首页 > 其他分享 >最短路

最短路

时间:2023-10-08 11:12:57浏览次数:31  
标签:松弛 短路 Bellman 节点 复杂度 dis

OI-wiki Link

最短路问题,顾名思义就是要求图上的某点到另外一点的最短距离,爆搜就不用说了。

令图上点数为 \(n\),边数为 \(m\)。

由于考虑的是最短路,那么包含负环的图就不能算了,没有最短这一说。

正权图最短路性质:任意两点间的最短路都不会经过重复的点和重复的边。

$$\texttt{Floyd}$$

优点

Floyd 可以求出两两节点间的最短路,码量较低,可以找到负权图的最短路。

缺点

时间复杂度高。


f[k][i][j] 表示在只经过(\(i\) 和 \(j\) 不算) \(1\sim k\) 的点的情况下 \(i\) 到 \(j\) 的最短路,显然 f[n][i][j] 就是原图上 \(i,j\) 之间最短路长度。

初始时 \(f_{0,i,j}=\begin{cases}0&i=j\\边权&i和j直接相连\\+\infty&i和j不相连 \end{cases}\),接着三重循环枚举 \(k,i,j(1\leqslant k,i,j \leqslant n)\),f[k][i][j] = min(f[k - 1][i][j], f[k - 1][i][k] + f[k - 1][k][j])

优化一下,第一维对结果无影响,变为二维 f[i][j]

时间复杂度:\(O(n^3+m)\),空间复杂度:\(O(n^2)\)

$$\texttt{Bellman-Ford}$$

优点

可以找到负权图的单源最短路,可以判负环。

缺点

时间复杂度仍比较高。


松弛操作:对于边 \(u\xrightarrow{w} v\),\(dis_v=\min(dis_v, dis_u+ w)\),如果\(dis_v\) 发生了改变,就称为松弛成功。

Bellman-Ford 就是不断尝试松弛图上的边,每次循环都枚举每条边,看是否能松弛,如果所有的边都无法松弛了,那么最短路也就求完了。

在最短路存在的情况下,最多只会经过 \(n -1\) 条边,那么松弛的次数也就不会超过 \(n-1\),当第 \(n\) 次松弛还能有松弛成功的点,就代表从原点开始能到达一个负环。

tips:如果想用 Bellman-Ford 判负环,那么最保守的方法是建立一个超级原点,向每个节点都连一条边权为 \(0\) 的边,在以它为原点做 Bellman-Ford 即可。

时间复杂度:\(O(n\times m)\),空间复杂度:\(O(n+m)\)。

队列优化 SPFA

关于 SPFA,它死了。

很显然,只有上一轮被更新的节点所连出去的边,才有可能是可以松弛的边,可以用队列维护哪些节点可能引起松弛操作。

SPFA 大多数情况下跑到快,可最差仍然是 \(O(n\times m)\) 的。

$$\texttt{Dijkstra}$$

优点

时间复杂度低,可以求出单源或者多源最短路。

缺点

一遇到负权就寄。


主要思想:使用优先队列存储一些访问到的节点的编号和最短路长度,优先队列肯定按最短路长度从小到大。

当取出了一个队头时,如果这个节点没有被取出来过,那么就记录好答案,将它所连出去的边都进行一次松弛。

当松弛 \(u\xrightarrow{w} v\) 时,如果 \(v\) 已经被取出来过,那么就不用放入优先队列了,因为在它之前的节点的最短路长度必然是非严格小于它的,不可能更优。

时间复杂度:\(O(m\log m)\),空间复杂度:\(O(n+m)\)。

标签:松弛,短路,Bellman,节点,复杂度,dis
From: https://www.cnblogs.com/wnsyou-blog/p/17747948.html

相关文章

  • 使用最短路径算法检查项目循环依赖
    最近项目组让我做一个自研的小工具,用来检查代码里的循环依赖,这里做下记录。思路由于工作是网络算路的,第一个想法就是通过路径计算来实现这个功能:把项目里test,resource等文件夹排除,剩下的每一个java文件可以算是对应一个类,把每个类看做是网络/路网里的节点,把类与类之间的依赖关......
  • 最短路径问题 java实现 源代码
    最短路径问题 java实现源代码下载地址:用到的资源文件 文件名 shortPath.propertiesbegin=/u59CB/u53D1/u5730/uFF1Aclear=/u6E05/u9664clearString=/u6E05/u695A/u7ED8/u56FE/u533A/u548C/u6240/u6709/u7684/u6587/u672CdrawLine=/u7ED8/u5236/u8DEF/u5F84end=/u76EE/......
  • 动态规划——DP与最短路 学习笔记
    动态规划——DP与最短路学习笔记例题:P2761软件补丁问题,很容易写出转移方程:\(dp_s\leftarrowdp_{s\setminusF_1\cupF_2}+t_i\),但是这样就出现了环,没有形成DAG就无法跑动态规划了,怎么办?可以将原问题转换为[最短路]:将原状态\(s\)记为一个点,将原转移路径记为一条边\(......
  • 同余最短路
    prologue都快csp-s了还啥也不会的废柴一根,真不知道能不能进队(痴人说梦)。mainbody同余最短路的适用题型当出现形如「给定n个整数,求这n个整数能拼凑出多少的其他整数(n个整数可以重复取)」,以及「给定n个整数,求这n个整数不能拼凑出的最小(最大)的整数」,或者「至少要拼几......
  • Johnson 全源最短路
    Johnson全源最短路Johnson和Floyd一样是能求出无负环图上任意两点间最短路径的算法。引入求任意两点间的最短路可以通过枚举起点,跑\(n\)次SPFA来解决,时间复杂度是\(O(n^2m)\)的,也可以用Floyd解决,复杂度为\(O(n^3)\)。或者我们可以跑\(n\)次堆优化的Dijkstra,......
  • P1144 最短路计数 题解
    Problem考察算法:拓扑排序+\(DP\)+\(Dijkstra\)。题目简述给出一个无向无权图,问从顶点\(1\)开始,到其他每个点的最短路有几条。思路先求出\(1\)号点到每个点的最短路\(d_i\)。分析每条边$(x,y)$:如果d[x]+1==d[y]:这条边有用。将所有有用的边拓扑排序......
  • 853. 有边数限制的最短路
    第一版err#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<cmath>#defineN505usingnamespacestd;intn,m,k,dis[N],cnt,hd[N],vis[N],x,y,z;structEdge{intto,nxt......
  • 单源最短路模板
    SPFA#include<bits/stdc++.h>#definerintregisterint#defineendl'\n'usingnamespacestd;constintN=1e5+5;constintM=1e6+5;constintinf=1e9;inth[N],e[M],ne[M],dist[N],w[M];intn,m,s,idx;queue<int>......
  • [算法分析与设计] 1. 全源最短路近似
    全源最短路(APSP)近似。有两种近似stretch\(k\).\(\delta(u,v)\leqd(u,v)\leqk\cdot\delta(u,v)\).surplus\(t\).\(\delta(u,v)\leqd(u,v)\leq\delta(u,v)+t\).其中,\(\delta(u,v)\)表示\(u,v\)间真实的最短路长度。先来考虑无权图上的surplus......
  • 最短路与次短路
    最短路算法不再赘述,假定我们已经求出了最短路,记\(f[x,y]\)为\(x\)到\(y\)的最短路。记\(g[x,y]\)为\(x\)到\(y\)的严格次短路。最短路树的定义单源最短路问题中,如果p1->p2->p3->...pn是一条最短路,就将它的边都加入图中。将所有的最短路径都这样处理,得到的图就......