floyd算法以及模板题(蓝桥公园)

⭐️floyd
Floyd-Warshall算法(英语:Floyd-Warshall algorithm),中文亦称弗洛伊德算法或佛洛依德算法,是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题,同时也被用于计算有向图的传递闭包[3]。

Floyd-Warshall算法的时间复杂度为O(n^3)空间复杂度为O( n ^2);

bellman-ford算法
dijkstra算法


具体原理

在这里插入图片描述

算法适用范围以及优缺点

Floyd算法的效率不高,不能用于大图,但是在某些场景下也有自己的优势,难以替代。Floyd算法是一种**“多源”最短路算法,一次计算能得到图中每一对结点之间(多对多)的最短路径。
  (1)能在一次计算后求得所有结点之间的最短距离,其他最短路径算法都做不到。(Bellman-Ford、Dijkstra、SPFA算法都是
“单源”最短路径算法,一次计算能得到一个起点到其他所有点(一对多)的最短路径)
  (2)代码极其简单,是最简单的最短路算法。三重循环结束后,所有点对之间的最短路都得到了。
  (3)效率低下,计算复杂度是O(n^3),只能用于n < 300的小规模的图。
  (4)能判断
负圈**。负圈是什么?若图中有权值为负的边,某个经过这个负边的环路,所有边长相加的总长度也是负数,这就是负圈。在这个负圈上每绕一圈,总长度就更小,从而陷入在负圈上兜圈子的死循环。Floyd算法很容易判断负圈,只要在算法运行过程出现任意一个dp[i][i] < 0就说明有负圈。因为dp[i][i]是从i出发,经过其他中转点绕一圈回到自己的最短路径,如果小于零,就存在负圈。
  下面的场景适用Floyd算法。
  (1)图的规模小,点数n < 400。计算复杂度 O(n^3)
限制了图的规模。这种小图不需要用其他算法,其他算法的代码长,写起来麻烦。
  (2)问题的解决和中转点有关。这是Floyd算法的核心思想,算法用DP方法遍历中转点来计算最短路。
  (3)路径在“兜圈子”,一个点可能多次经过。这是Floyd算法的特长,其他路径算法都不行。
  (4)允许多次询问不同点对之间的最短路。这是Floyd算法的优势。


模板题

问题描述

在这里插入图片描述


格式输入

在这里插入图片描述


格式输出

在这里插入图片描述


样例输入

3 3 3
1 2 1
1 3 5
2 3 2
1 2
1 3
2 3


样例输出

1
3
2


评测用例规模与约定

在这里插入图片描述


解析

根据floyd算法计算q个观景计划的最短路径


参考程序

#include <bits/stdc++.h>
using namespace std;
const long long INF = 0x3f3f3f3f3f3f3f3fLL; 
const int N = 405;
long long dp[N][N];
int n,m,q;
void input(){
for(int i = 1; i <= n; i++)
 for(int j = 1; j <= n; j++)   dp[i][j] = INF;
    for(int i = 1; i <= m; i++){
        int u,v;long long w;
        cin >> u >> v >> w;
        dp[u][v]=dp[v][u] = min(dp[u][v] , w);  
    }
}
void floyd(){
    for(int k = 1; k <= n; k++)
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k][j]);
}
void output(){    
    while(q--){
        int s, t; cin >> s >>t;
        if(dp[s][t]==INF) cout << "-1" <<endl;
        else if(s==t) cout << "0" <<endl;    
        else          cout <<dp[s][t]<<endl;
    }
}
int main(){
    cin >> n>> m >> q;
    input();     floyd();    output();
    return 0;
}

以个人刷题整理为目的,如若侵权,请联系删除~

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值