FLoyd算法的入门与应用

news2025/1/16 6:34:13

目录

一、前言

二、FLoyd算法

1、最短路问题

2、Floyd算法 

3、Floyd的特点

4、Floyd算法思想:动态规划

三、例题

1、蓝桥公园(lanqiaoOJ题号1121)

2、路径(2021年初赛 lanqiaoOJ题号1460)


一、前言

本文主要讲了最短路问题,以及解决最短路问题的Floyd算法概念与两道简单的相关例题。

二、FLoyd算法

1、最短路问题

  • 最广为人知的图论问题。
  • 简单图的最短路径

① 树上的路径:任意2点之间只有一条路径

② 所有边长都为 1 的图:用 BFS 搜最短路径,复杂度O(n+m)

  • 普通图的最短路径

① 边长:不一定等于 1,而且可能为负数

② 算法:Floyd、Dijkstra、SPFA 等,各有应用场景,不可互相替代

【最短路算法比较】

2、Floyd算法 

  • 最简单的最短路径算法,代码仅有5行
  • 存图:最简单的矩阵存图
  • 易懂,比暴力的搜索更简单易懂
  • 效率不高,不能用于大图
  • 在某些场景下有自己的优势,难以替代。
def Floyd():
    for k in range(1,n+1):
        for i in range(1,n+1):
            for j in range(1,n+1):
                if dp[i][k]+dp[k][j]<dp[i][j]:
                    dp[i][j]=dp[i][k]+dp[k][j]

3、Floyd的特点

  • Floyd算法:“多源” 最短路算法,一次计算能得到图中每一对结点之间 (多对多) 的最短路径。
  • Dijkstra、 Bellman-Ford、 SPFA算法:"单源” 最短路径算法 (Single sourceshortest path algorithm),一次计算能得到一个起点到其他所有点 (一对多) 的最短路径。
  • 在截止目前的蓝桥杯大赛中,Floyd算法是最常见的最短路径算法。

4、Floyd算法思想:动态规划

动态规划:求图上两点 i、j 之间的最短距离,按 “从小图到全图” 的步骤,在逐步扩大图的过程中计算和更新最短路。

定义状态:dp[k][i][j],i、j、k 是点的编号,范围 1~n。状态 dp[k][i][j] 表示在包含 1~k 点的子图上,点对 i、j 之间的最短路。

状态转移方程:从子图 1~k-1 扩展到子图 1~k

dp[k][i][j] = min(dp[k-1][i][j], dp[k-1][i][k] +dp[k-1][k][j])

  • 虚线圆圈:包含1~k-1点的子图。
  • dp[k-1][i][j]:虚线子图内的点对 i、j 的最短路;
  • dp[k-1][i][k]+dp[k-1][k][j]:经过 k 点的新路径的长度,即这条路径从 i 出发,先到 k,再从 k 到终点 j。
  • 比较:不经过 k 的最短路径 dp[k-1][i][j] 和经过 k 的新路径,较小者就是新的 dp[k][i][j]。

  • k 从 1 逐步扩展到 n:最后得到的 dp[n][i][j] 是点对 i、j 之间的最短路径长度。
  • 初值 dp[0][i][j]:若 i、j 是直连的,就是它们的边长;若不直连,赋值为无穷大。
  • i、j 是任意点对:计算结束后得到了所有点对之间的最短路。 

【方程的简化】(这里留个眼)

dp[k][i][j] = min(dp[k-1][i][j], dp[k-1][i][k]+dp[k-1][k][j])

用滚动数组简化:

dp[i][j]=min(dp[i][j], dp[i][k] + dp[k][j])

【Floyd算法总结】

  • 1)在一次计算后求得所有结点之间的最短距离。
  • 2)代码极其简单,是最简单的最短路算法。
  • 3)效率低下,计算复杂度是 O(n^3),只能用于 n <300 的小规模的图。
  • 4)存图用邻接矩阵 dp[][] 。因为 Floyd 算法计算的结果是所有点对之间的最短路,本身就需要 n^2 的空间,用矩阵存储最合适。
  • 5)能判断负圈。负圈:若图中有权值为负的边,某个经过这个负边的环路,所有边长相加的总长度也是负数,这就是负圈。在这个负圈上每绕一圈,总长度就更小,从而陷入在负圈上兜圈子的死循环。
  • Floyd算法很容易判断负圈,只要在算法运行过程出现任意一个 dp[i][j]<0 就说明有负圈。因为 dp[i][j] 是从 i 出发,经过其他中转点绕一圈回到自己的最短路径,如果小于零,就存在负圈。

三、例题

1、蓝桥公园(lanqiaoOJ题号1121)

【题目描述】

小明来到了蓝桥公园。已知公园有 N 个景点,景点和景点之间一共有 M 条道路。小明有 Q 个观景计划,每个计划包含一个起点 st 和一个终点 ed,表示他想从 st 去到 ed。但是小明的体力有限,对于每个计划他想走最少的路完成,你可以帮帮他吗?

【输入描述】

输入第一行包含三个正整数 N, M, Q。第 2 到 M+1 行每行包含三个正整数 u, v, w,表示 u、v 之间存在一条距离为 w 的路。第 M+2 到 M+Q-1 行每行包含两个正整数 st, ed,其含义如题所述。

1<=N<=400, 1<=M<=N*(N-1)/2, Q<=10^3, 1<=u, v, st, ed<=n, 1<=w<=10^9

【输出描述】

输出共 Q 行,对应输入数据中的查询。若无法从 st 到达 ed 则输出 -1。

def floyd():
    global mp
    global N
    global M
    global Q
    for k in range(1,N+1):
        for i in range(1,N+1):
            for j in range(1,N+1):
                mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j])
        
N,M,Q=map(int,input().split())
mp=[[1100000000]*(M+2) for _ in range(N+2)]
for _ in range(M):
    u,v,w=map(int,input().split())
    w=min(mp[u][v],w)               #考虑重边,选最小权值那条
    mp[u][v]=w
    mp[v][u]=w
floyd()
for _ in range(Q):
    st,ed=map(int,input().split())
    if mp[st][ed]==1100000000:      #st无法到达ed
        print(-1)
    elif st==ed:                    #有可能兜一圈回到起点呢,所以要特判
        print(0)
    else:
        print(mp[st][ed])

2、路径(2021年初赛 lanqiaoOJ题号1460)

填空题

【题目描述】

小蓝的图由 2021 个结点组成,依次编号1至2021。对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条长度为 a 和 b 的最小公倍数的无向边相连。例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为75。

请计算,结点 1 和结点 2021 之间的最短路径长度是多少。

【常规的floyd】:运行时间长达30分钟!

from math import *
def lcm(x,y):
    return x//gcd(x,y)*y    #求最小公倍数
dp=[[int(0x3f3f3f3f3f3f3f3f) for _ in range(2022)] for _ in range(2022)]

def floyd():
    global dp
    for k in range(1,2022):
        for i in range(1,2022):
            for j in range(1,2022):
                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])

for i in range(1,2022):
    for j in range(1,2022):
        if abs(i-j)<=21:
            dp[i][j]=lcm(i,j)
floyd()
print(dp[1][2021])

【简化版floyd】

from math import *
def lcm(x,y):
    return x//gcd(x,y)*y    #求最小公倍数
dp=[[int(0x3f3f3f3f3f3f3f3f) for _ in range(2022)] for _ in range(2022)]

def floyd():
    global dp
    for k in range(1,2022):
        #for i in range(1,2022):
        for i in range(1,2):
            for j in range(1,2022):
                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])

for i in range(1,2022):
    for j in range(1,2022):
        if abs(i-j)<=21:
            dp[i][j]=lcm(i,j)
floyd()
print(dp[1][2021])

我们只求点 1 到其他点的最短路就行!这实际上这变成了 Bellman-ford 算法。

【Bellman-ford更简洁的写法】

from math import *
def lcm(x,y):
    return x//gcd(x,y)*y    #求最小公倍数
dp=[int(0x3f3f3f3f3f3f3f3f)]*2022   #dp[i]:点i到点1的最短路径
d[1]=0
for i in range(1,2022):     #点i
    for j in range(i+1,i+22):   #和i有边的点j
        if j>2021:
            break
        dp[j]=min(dp[j],dp[i]+lcm(i,j))     #更新最短路
print(dp[2021])

以上,FLoyd算法的入门与应用

祝好

 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/387556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cannot start compiler The output path is not specified for module mystatic(已解决)

1.背景&#xff1a;今天在idea上写了一些代码&#xff0c;右键run竟然跑不起来了&#xff0c;而且右下角的Event Log还报错。报错内容如下图&#xff1a;2.报错原因&#xff1a;项目代码和编译器的输出路径不在一块&#xff0c;导致idea无法找到模块的output path&#xff08;输…

Docker--(六)--Docker资源限制

前言系统压力测试Cpu资源限制Mem资源限制IO 资源限制【扩展】 1.前言 在使用 Docker 运行容器时&#xff0c;一台主机上可能会运行几百个容器&#xff0c;这些容器虽然互相隔离&#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&#x…

VUE中给对象添加新属性时,界面不刷新怎么办

一、直接添加属性的问题 举例&#xff1a; 定义一个p标签&#xff0c;通过v-for指令进行遍历 然后给botton标签绑定点击事件&#xff0c;我们预期点击按钮时&#xff0c;数据新增一个属性&#xff0c;界面也 新增一行。 <p v-for"(value,key) in item" :key&qu…

18.用于大型程序的工具

文章目录用于大型程序的工具18.1异常处理18.1.1抛出异常栈展开栈展开过程中对象被自动销毁析构函数与异常异常对象18.1.2捕获异常查找匹配的处理代码重新抛出捕获所有异常的处理代码18.1.3函数try语句块与构造函数18.1.4noexcept异常说明违反异常说明异常说明的实参noexcept运算…

Potions (Hard Version) and (Easy Version)(背包DP + 反悔贪心)

[TOC](Potions (Hard Version) and (Easy Version)) 一、Potions(Easy Version) 1、问题 2、分析&#xff08;背包DP 贪心&#xff09; 简而言之就是我们需要从左到右开始选数字&#xff0c;选的过程中我们需要保证我们选的数字的和始终是大于等于0的&#xff0c;在满足这个…

零售电子货架标签解决方案

数字价格标签是一种新的零售趋势。它(ESLs)弥补了店内管理面临的挑战&#xff0c;是新零售的里程碑。电子货架标签(ESLs)为顾客开启了一段愉快的旅程。他们希望更多地参与到购物环境中&#xff0c;并从与商店的更深入互动中受益。 什么是电子货架标签&#xff1f; ESL系统用于…

C语言实现通讯录(实现增删查改显示功能)面向对象的编程

前言 大家好&#xff0c;我是程序猿爱打拳。今天我给大家带来的是C语言实现通讯录&#xff0c;主要的实现方式是结构体。 目录 1.设计思想 2.各个模块的实现 3.最终效果展示 1.设计思想 首先&#xff0c;我们在设计一个通讯录的时候。我们得知道通讯录的基本功能是什么。比…

python第一周作业

作业1&#xff1a;1、PPT上五个控制台界面2、要求定义两个数&#xff0c;并且交换它们的值&#xff08;请使用多种方式&#xff0c;越多越好&#xff09;作业1作业2&#xff1a;判断一个数&#xff0c;是否是2的指数2的指数0000 0010 0000 00010000 0100 0000 00110000 1000 00…

EXCEL-职业版本(2)

Excel-职业版本&#xff08;2&#xff09; 定位 1.如何快速定位到不连续的空值&#xff0c;填充为0 1.在任意空单元格里复制0 2.选中数据区域CtrlA 3.CtrlG 4.选择【定位条件】 5.选择【空值】 6.ctrlV 粘贴 即可 2.怎么一次性计算每个小组的数量 单价和金额的和? 1.选中…

Spring——是什么?作用?内容?用到的设计模式?

目录 什么是spring&#xff1f; spring是为了解决什么问题而衍生的&#xff1f;&#xff08;历史&#xff09;Spring解决了实际生产中的什么问题&#xff1f; spring包含了哪些部分&#xff1f;&#xff08;组成&#xff09; Spring的特点是什么&#xff1f; spring框架中…

K_A14_004 基于STM32等单片机驱动旋转角度传感器模块 串口与OLED0.96双显示

K_A14_004 基于STM32等单片机驱动旋转角度传感器模块 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RC旋转角度传感器模块1.2、STM32F103C8T6旋转角度传感器模块五、…

Arthas阿尔萨斯的使用安装详细教程

Arthas阿尔萨斯的使用安装详细教程一、阿尔萨斯能解决什么什么问题二、安装与命令三、实际应用四、自学途径本篇文章是自学B站“御风大世界”视频的提炼和总结。 原视频见&#xff1a;Arthas使用教程 一、阿尔萨斯能解决什么什么问题 alibaba出品线上JVM监控诊断利器 1、是一…

Flask源码篇:Flask路由规则与请求匹配过程(超详细,易懂)

目录1 启动时路由相关操作&#xff08;1&#xff09;分析app.route()&#xff08;2&#xff09;分析add_url_rule()&#xff08;3&#xff09;分析Rule类&#xff08;4&#xff09;分析Map类&#xff08;5&#xff09;分析MapAdapter类&#xff08;6&#xff09;分析 url_rule_…

深度学习技巧应用2-神经网络中的‘残差连接’

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍 深度学习技巧应用2-神经网络中的‘残差连接’。 一、残差连接介绍 残差连接是一种神经网络中的一种运用技巧。由于深层网络容易出现梯度消失或梯度爆炸的问题&#xff0c;因此可以通过残差连接的方式&#xff0c;将网…

C++数据结构 —— 红黑树

目录 1.红黑树概念 2.红黑树节点的定义 3.红黑树的插入操作 4.红黑树的调整动作 4.1调整动作1 4.2调整动作2 4.3调整动作3 4.4插入算法的完整代码 4.5验证红黑树 4.6完整代码 1.红黑树概念 与AVL树一样&#xff0c;红黑树也是map、set等关联式容器的底层结构。但红黑…

大数据开发学习好找工作么

工作到底好不好找&#xff0c;市场需求是一方面&#xff0c;更多的还是要看个人成长背景和实际能力抛开两点都不谈就单说好找或者不好找纯属有点耍流氓了大数据需求越来越多&#xff0c;只有技术在手不愁找不到工作。 大数据开发主要是负责大数据挖掘&#xff0c;大数据清洗处…

谷歌验证码的使用

1. 表单重复提交之验证码 1.1 表单重复提交三种常见情况 提交完表单。服务器使用请求转来进行页面跳转。这个时候&#xff0c;用户按下功能键 F5&#xff0c;就会发起最后一次的请求。造成表单重复提交问题。解决方法&#xff1a;使用重定向来进行跳转用户正常提交服务器&…

行为型模式之策略模式

行为型模式&#xff1a;类和对象如何交互&#xff0c;划分责任和算法&#xff0c;即对象之间通信。 概念 策略模式是对算法的包装&#xff0c;是把使用算法的责任和算法本身分割开来&#xff0c;委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面…

Servlet请求响应

文章目录Servlet请求响应进阶内容回顾Servlet 体系结构get/post 请求Servlet 的生命周期web.xml 配置文件HttpServletRequest 接口文件上传HttpServletResponse 接口文件下载响应表格的案例转发与重定向简介请求转发原理请求转发案例重定向原理重定义与请求转发的区别Servlet请…

分巧克力(二分)

儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。小明一共有 N 块巧克力&#xff0c;其中第 i 块是 HiWi 的方格组成的长方形。为了公平起见&#xff0c;小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足&#xff1a;形…