数据结构与算法学习笔记----Floyd算法

数据结构与算法学习笔记----Floyd算法

@@ author: 明月清了个风

@@ first publish time: 2024.12.20

Floyd算法

Floyd一种基于动态规划的最短路径算法,用于求出加权有向图中的任意两点之间的最短路径问题,并且适用于图中可能存在负权边 的情况,但是要求不能有负权环 ,它能有效的求出图中所有节点之间的最短路径,适用稠密图

基本思路

Floyd通过不断考虑每个节点作为中间节点,更新每对节点之间的最短距离

  1. 初始化

    初始化dist[][]数组,对于任意两点之间之间距离初始化为无穷大,如有边存在,则初始化为边长。

  2. 状态转移方程

    对于所有节点对 i i i和 j j j,使用每个中间节点 k k k更新他们之间的最短路径

    d i s t [ i ] [ j ] = m i n ( d i s t [ i ] [ j ] , d i s t [ i ] [ k ] + d i s t [ k ] [ j ] ) (1) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]) \tag{1} dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j])(1)

    对应于一组 f ( k , i , j ) f(k,i,j) f(k,i,j)来说,它表示的是经过 1 ∼ k 1 \sim k 1∼k这些点,从 i i i到 j j j的最短距离,原始状态转移方程为

    d i s t [ k , i , j ] = d i s t [ k − 1 , i , k ] + d i s t [ k − 1 , k , j ] (2) dist[k, i, j] = dist[k - 1, i, k] + dist[k - 1, k, j] \tag{2} dist[k,i,j]=dist[k−1,i,k]+dist[k−1,k,j](2)

    式中:

    d i s t [ k , i , j ] dist[k, i, j] dist[k,i,j]表示经过 1 ∼ k 1 \sim k 1∼k这些点,从 i i i到 j j j的最短距离;

    d i s t [ k − 1 , i , k ] dist[k - 1, i, k] dist[k−1,i,k]表示经过 1 ∼ k − 1 1 \sim k - 1 1∼k−1这些点,先从 i i i到 k k k的最短距离;

    d i s t [ k − 1 , k , j ] dist[k - 1, k, j] dist[k−1,k,j]表示经过 1 ∼ k − 1 1 \sim k - 1 1∼k−1这些点,从 k k k到 j j j的最短距离。

    最高位 k k k可以省略,因此式(2)转化为式(1)。

注意点

需要注意的是,floyd算法和bellman-ford算法同样可能会因为负权更新没有通路的两点之间的距离,因此最后的无法到达的判断也要大于一个大数,至于大数的选择就要看数据范围了,比如这道题中的最多会有 20000 20000 20000条边,每条最长为 10000 10000 10000,这意味这两者之间没有通路的两点本来应该无穷大的距离最多会减去 20000 × 10000 20000 \times 10000 20000×10000,也就是 1 0 8 10^8 108数量级,所以这里不能像之前判断是否大于0x3f3f3f3f / 2,因为这个数是有可能取到的。

时间复杂度

Floyd算法的时间复杂度为 O ( n 3 ) O(n^3) O(n3), n n n表示节点数。

Acwing 854. Floyd求最短路

原题链接\]([854. Floyd求最短路 - AcWing题库](https://www.acwing.com/problem/content/856/)) 给定一个 n n n个点 m m m条边的有向图,图中可能存在重边和自环,边权可能为负数。 再给定 k k k个询问,每个询问包含两个整数 x x x和 y y y,表示查询从点 x x x到点 y y y的最短距离,如果路径不存在,则输出`impossible`。 #### 输入格式 第一行包含三个整数 n n n, m m m, k k k。 接下来 m m m行,每行包含三个整数 x x x、 y y y、 z z z,表示存在一条从点 x x x到点 y y y的有向边,边长为 z z z。 接下来 k k k行,每行包含两个整数 x x x, y y y,表示询问点 x x x到点 y y y的最短距离。 #### 输出格式 共 k k k行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出`impossible`. #### 数据范围 1 ≤ n ≤ 200 1 \\leq n \\leq 200 1≤n≤200, 1 ≤ k ≤ n 2 1 \\leq k \\leq n\^2 1≤k≤n2, 1 ≤ m ≤ 20000 1 \\leq m \\leq 20000 1≤m≤20000, 图中涉及边长绝对值均不超过 10000 10000 10000. #### 代码 ```cpp #include #include #include #include using namespace std; const int N = 210, inf = 1e9; int dist[N][N]; int n, m, k; void floyd() { for(int k = 1; k <= n; k ++) for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); } int main() { cin >> n >> m >> k; for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) if(i == j) dist[i][j] = 0; else dist[i][j] = inf; for(int i = 0; i < m; i ++) { int a, b, c; cin >> a >> b >> c; dist[a][b] = min(dist[a][b], c); } floyd(); while(k --) { int x, y; cin >> x >> y; if(dist[x][y] > inf / 2) puts("impossible"); else cout << dist[x][y] << endl; } return 0; } ```

相关推荐
冷崖3 小时前
MySQL异步连接池的学习(五)
学习·mysql
知识分享小能手3 小时前
Vue3 学习教程,从入门到精通,Axios 在 Vue 3 中的使用指南(37)
前端·javascript·vue.js·学习·typescript·vue·vue3
所愿ღ4 小时前
JavaWeb-Servlet基础
笔记·servlet
岑梓铭5 小时前
考研408《计算机组成原理》复习笔记,第五章(2)——CPU指令执行过程
笔记·考研·408·计算机组成原理·计组
No0d1es7 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
焄塰7 小时前
Ansible 管理变量和事实
学习·centos·ansible
oe10198 小时前
读From GPT-2 to gpt-oss: Analyzing the Architectural Advances(续)
笔记·gpt·学习
大阳1238 小时前
线程(基本概念和相关命令)
开发语言·数据结构·经验分享·算法·线程·学习经验
weixin_3077791310 小时前
VS Code配置MinGW64编译GNU 科学库 (GSL)
开发语言·c++·vscode·算法
学行库小秘10 小时前
ANN神经网络回归预测模型
人工智能·python·深度学习·神经网络·算法·机器学习·回归