Floyd 算法

Floyd 算法

1.Floyd算法介绍

Floyd算法是最短路问题里的一种,用来求任意一对顶点之间的最短路径。时间复杂度为 \(O(n^3)\),适用于负边权的情况。

2.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≤n≤200,\)

\(1≤k≤n2\)

\(1≤m≤20000,\)

图中涉及边长绝对值均不超过 \(10000\)

输入样例:

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

输出样例:

impossible
1

3.Floyd算法思路

基于动态规划实现。

如果我们已经知道了图中任意两点间只允许以编号 \(<=k-1\) 的点作为中转时的最短路,就能以此推出任意两点间只允许以编号 \(<=k\) 的点作为中转时的最短路。

核心代码

if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j]

4.Floyd算法代码

#include<iostream>
using namespace std;
const int N=205;
int n,m,k;
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(){
    cin>>n>>m>>k;
    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]=0x3f3f3f3f;//否则存正无穷 
    for(int i=1;i<=m;i++){
        int a,b,w;
        cin>>a>>b>>w;
        d[a][b]=min(d[a][b],w);
    }
    floyd();
    for(int i=1;i<=k;i++){
        int x,y;
        cin>>x>>y;
        if(d[x][y]>0x3f3f3f3f/2) cout<<"impossible"<<endl;
        else cout<<d[x][y]<<endl;
    }
    return 0;
}  

完awa~

如果觉得还行就给个赞吧,您的支持就是本蒟蒻最大的动力。

posted @ 2022-07-19 17:25  Rainforests  阅读(177)  评论(0)    收藏  举报