floyd算法求最短路

给定一个 \(n\) 个点 \(m\) 条边的有向图,图中可能存在重边和自环,边权可能为负数。

再给定 \(k\) 个询问,每个询问包含两个整数 \(x\)\(y\),表示查询从点 \(x\) 到点 \(y\) 的最短距离,如果路径不存在,则输出 impossible

数据保证图中不存在负权回路。

输入格式

第一行包含三个整数 \(n,m,k\)

接下来 \(m\) 行,每行包含三个整数 \(x,y,z\),表示存在一条从点 \(x\) 到点 \(y\) 的有向边,边长为 \(z\)

接下来 \(k\) 行,每行包含两个整数 \(x,y\),表示询问点 \(x\) 到点 \(y\) 的最短距离。

输出格式

\(k\) 行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出 impossible

数据范围

\(1 \le n \le 200\),
\(1 \le k \le n^2\)
\(1 \le m \le 20000\),
图中涉及边长绝对值均不超过 \(10000\)

输入样例:

3 3 2
1 2 1
2 3 2
1 3 1
2 1
1 3

输出样例:

impossible
1

分析

弗洛伊德(Floyd)算法是一种用于解决图中所有节点对之间最短路径的经典算法,也称为全源最短路径算法。与迪杰斯特拉算法不同,弗洛伊德算法可以处理边权重为负值的情况。该算法通过动态规划的思想,逐步更新节点之间的最短路径距离。

以下是弗洛伊德算法的基本原理:

初始化:创建一个距离矩阵,其中矩阵中的元素表示节点之间的直接距离。如果两节点之间有直接边相连,则距离矩阵中对应位置的值为边的权重,否则为一个较大的值(表示不可达)。同时,对角线上的元素设为0,表示每个节点到自身的距离为0。

通过遍历每个中间节点:对于每个节点k,遍历所有节点i和节点j,尝试通过节点k来更新节点i到节点j的最短路径距离。具体做法是比较从节点i经过节点k到节点j的距离与节点i直接到节点j的距离,如果前者更小,则更新距离矩阵中的节点i到节点j的值。

重复步骤2,直到遍历完所有的中间节点。每次更新后,距离矩阵中的值逐步代表了节点之间的最短路径距离。

最终得到的距离矩阵即为所有节点对之间的最短路径距离。

弗洛伊德算法通过不断地遍历所有节点对和中间节点,逐步更新最短路径距离矩阵,从而获得所有节点对之间的最短路径。算法的时间复杂度为 O(V^3),其中 V 为节点数。虽然算法效率相对较低,但它的优点是可以处理包括负权边在内的各种情况,同时可以一次性计算出所有节点对之间的最短路径,适用于稀疏图和稠密图。

代码实现

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 210, INF = 1e9;

int n, m, Q;
int d[N][N];

void floyd()
{
    for (int k = 1; k <= n; k ++ )
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}

int main()
{
    scanf("%d%d%d", &n, &m, &Q);

    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= n; j ++ )
            if (i == j) d[i][j] = 0;
            else d[i][j] = INF;

    while (m -- )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        d[a][b] = min(d[a][b], c);
    }

    floyd();

    while (Q -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);

        int t = d[a][b];
        if (t > INF / 2) puts("impossible");
        else printf("%d\n", t);
    }

    return 0;
}

//https://www.acwing.com/activity/content/code/content/48531/
//来源:AcWing

posted @ 2023-08-30 13:19  LongDz  阅读(56)  评论(0)    收藏  举报