数据结构与算法学习笔记----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) distij = min(distij, distik + distkj) \tag{1} distij=min(distij,distik+distkj)(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) distk, i, j = distk - 1, i, k + distk - 1, k, j \tag{2} distk,i,j=distk−1,i,k+distk−1,k,j(2)

    式中:

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

    d i s t k − 1 , i , k distk - 1, i, k distk−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 distk - 1, k, j distk−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题库)

给定一个 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 <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

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;
}
相关推荐
朝朝辞暮i38 分钟前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
Evand J1 小时前
【MATLAB例程】三维RRT+APF避障路径规划与到达角(AOA)定位算法|三维路径优化与定位仿真例程
算法·matlab·路径规划·代码·定位·rrt·aoa
weixin_307779132 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
朝朝辞暮i3 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
by209993 小时前
学会使用std::string类,并理解其内部是如何管理字符串的详细阐述(上)
c++·笔记·字符串·类和对象·string
朝朝辞暮i3 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
青柠之夏cc4 小时前
AI与教育:个性化学习助手让“因材施教“成为现实,但代价是隐私?
人工智能·学习
Godspeed Zhao4 小时前
现代智能雷达技术14——算法(0)
线性代数·算法·雷达
可乐ea4 小时前
Agent 模型分级升级路由:用置信度阈值把贵模型省下来
人工智能·算法·机器学习·结构化输出·置信度路由·模型升级路由·大模型成本优化
笑鸿的学习笔记4 小时前
C++笔记之大块顺序写
java·c++·笔记