代码随想录训练营 Day62打卡 图论part11 Floyd 算法 A * 算法

代码随想录训练营 Day62打卡 图论part11

Floyd 算法

例题:卡码97. 小明逛公园

题目描述
小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短的路径。
给定一个公园景点图,图中有 N 个景点(编号为 1 到 N),以及 M 条双向道路连接着这些景点。每条道路上行走的距离都是已知的。
小明有 Q 个观景计划,每个计划都有一个起点 start 和一个终点 end,表示他想从景点 start 前往景点 end。由于小明希望节省体力,他想知道每个观景计划中从起点到终点的最短路径长度。 请你帮助小明计算出每个观景计划的最短路径长度。
输入描述
第一行包含两个整数 N, M, 分别表示景点的数量和道路的数量。
接下来的 M 行,每行包含三个整数 u, v, w,表示景点 u 和景点 v 之间有一条长度为 w 的双向道路。
接下里的一行包含一个整数 Q,表示观景计划的数量。
接下来的 Q 行,每行包含两个整数 start, end,表示一个观景计划的起点和终点。
输出描述
对于每个观景计划,输出一行表示从起点到终点的最短路径长度。如果两个景点之间不存在路径,则输出 -1。
输入示例
7 3
2 3 4
3 6 6
4 7 8
2
2 3
3 4
输出示例
4
-1
提示信息
从 2 到 3 的路径长度为 4,3 到 4 之间并没有道路。

本题要求使用 Floyd-Warshall 算法 解决 多源最短路径 问题,具体来说,要计算每两个景点之间的最短路径。与之前学过的 Dijkstra 或 Bellman-Ford 算法不同,Floyd-Warshall 可以处理多个起点和多个终点之间的最短路径,且适用于权值为正或负的边,但不允许存在负权回路。

核心思想

Floyd-Warshall 算法的核心思想
Floyd-Warshall 算法的核心思想是通过动态规划,逐步引入中间节点来优化路径。对于每个可能的中间节点 k,检查通过该中间节点的路径是否比原有的直接路径更短。如果更短,则更新路径长度。

具体地,假设我们有 N 个节点,Floyd-Warshall 算法可以通过三重循环来计算所有节点对之间的最短路径:

  • 外层循环枚举所有可能的中间节点 k。
  • 中间两层循环枚举起点 i 和终点 j,并检查是否通过中间节点 k 能找到更短的路径。

递推公式为:

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

其中:
grid[i][j] 表示节点 i 到节点 j 的最短路径。
grid[i][k] + grid[k][j] 表示通过中间节点 k 走到 j 的路径长度。
我们取两者的最小值,来不断更新最短路径。

遍历顺序
外层 k 遍历中间节点。内层 i, j 遍历所有起点和终点。

代码实现

if __name__ == '__main__':max_int = 10005  # 设置一个非常大的数表示节点之间不可达# 读取节点数 n 和边数 mn, m = map(int, input().split())# 初始化二维数组 grid,存储最短路径,初始值为无穷大grid = [[max_int] * (n + 1) for _ in range(n + 1)]# 自己到自己的最短路径为 0for i in range(1, n + 1):grid[i][i] = 0# 读取边的信息,双向边,初始化各边的距离for _ in range(m):p1, p2, w = map(int, input().split())grid[p1][p2] = min(grid[p1][p2], w)  # 避免多条边,取最短边grid[p2][p1] = min(grid[p2][p1], w)# 使用 Floyd-Warshall 算法更新所有节点对之间的最短路径for k in range(1, n + 1):for i in range(1, n + 1):for j in range(1, n + 1):grid[i][j] = min(grid[i][j], grid[i][k] + grid[k][j])# 读取 Q 个查询,输出最短路径q = int(input())  # 观景计划数量for _ in range(q):start, end = map(int, input().split())if grid[start][end] == max_int:print(-1)  # 不可达else:print(grid[start][end])  # 输出最短路径

卡码题目链接
题目文章讲解

A * 算法

例题:97. 小明逛公园

题目描述
在象棋中,马和象的移动规则分别是“马走日”和“象走田”。现给定骑士的起始坐标和目标坐标,要求根据骑士的移动规则,计算从起点到达目标点所需的最短步数。
棋盘大小 1000 x 1000(棋盘的 x 和 y 坐标均在 [1, 1000] 区间内,包含边界)
输入描述
第一行包含一个整数 n,表示测试用例的数量,1 <= n <= 100。
接下来的 n 行,每行包含四个整数 a1, a2, b1, b2,分别表示骑士的起始位置 (a1, a2) 和目标位置 (b1, b2)。
输出描述
输出共 n 行,每行输出一个整数,表示骑士从起点到目标点的最短路径长度。
输入示例
6
5 2 5 4
1 1 2 2
1 1 8 8
1 1 8 7
2 1 3 3
4 6 4 6
输出示例
2
4
6
5
1
0
提示信息
骑士移动规则如图,红色是起始位置,黄色是骑士可以走的地方。

实现思路

本题是典型的求最短路径问题。棋盘为1000x1000,我们需要计算骑士(象棋中的“马”)从起始位置移动到目标位置所需的最短步数。

骑士的移动规则:骑士每次可以向8个不同方向移动,具体为“日”字形移动方式:即每次水平或垂直移动两格,同时在垂直或水平方向再移动一格。
A*算法:A算法是一种启发式搜索算法,使用估计代价函数来加速路径搜索。在A中,优先队列会根据状态的代价(F = G + H)来排序。

  • G是从起点到当前节点的实际代价(即步数)。
  • H是当前节点到目标节点的估计代价(启发式函数),可以使用欧几里得距离的平方来估算,避免开根号的浮点运算。

具体步骤:

  1. 定义骑士的8个可能移动方向。
  2. 使用优先队列(最小堆)存储每个状态,根据F值(G+H)进行排序,F值越小优先级越高。
  3. 初始化状态:将起点加入优先队列,开始A*搜索。
  4. 扩展节点:从优先队列中取出F值最小的节点,检查是否到达目标点。如果没有到达,则继续将其8个可能的移动加入优先队列。
  5. 剪枝:对于越界的点或已经访问过的点,跳过处理。
  6. 最终输出结果:当找到目标点时,输出最短步数。

代码实现

import heapq# 定义骑士的8个移动方向
dir = [(-2, -1), (-2, 1), (-1, 2), (1, 2), (2, 1), (2, -1), (1, -2), (-1, -2)]# 启发式函数,计算当前节点到目标节点的估计代价(使用欧几里得距离的平方)
def heuristic(x1, y1, x2, y2):return (x1 - x2) ** 2 + (y1 - y2) ** 2# A*算法函数,返回从起点到终点的最短路径
def astar(a1, a2, b1, b2):# 初始化棋盘,用于记录每个点的最短路径步数moves = [[0] * 1001 for _ in range(1001)]# 定义优先队列,初始加入起点pq = []heapq.heappush(pq, (0, a1, a2))  # (F值, x, y)# 处理队列,开始A*搜索while pq:f, x, y = heapq.heappop(pq)# 如果当前点已经到达目标点,返回步数if x == b1 and y == b2:return moves[x][y]# 扩展当前点的8个移动方向for dx, dy in dir:nx, ny = x + dx, y + dy# 判断是否越界if 1 <= nx <= 1000 and 1 <= ny <= 1000:if moves[nx][ny] == 0:  # 如果该点还没有访问过moves[nx][ny] = moves[x][y] + 1  # 更新步数g = moves[nx][ny] * 5  # G值,每次移动的代价是5h = heuristic(nx, ny, b1, b2)  # 计算启发式估计值Hf = g + h  # 计算F值heapq.heappush(pq, (f, nx, ny))  # 将新状态加入优先队列return -1  # 如果无法到达目标点# 处理输入输出
if __name__ == "__main__":n = int(input())  # 读取测试用例数量for _ in range(n):a1, a2, b1, b2 = map(int, input().split())  # 读取起点和终点坐标if a1 == b1 and a2 == b2:print(0)  # 如果起点和终点相同,步数为0else:print(astar(a1, a2, b1, b2))  # 输出从起点到终点的最短步数

代码详解:

  1. dir:定义骑士的8个移动方向。

  2. heuristic:启发式函数,计算当前节点到目标节点的欧几里得距离的平方,作为H值。

  3. astar:A*搜索算法的核心函数:

    使用heapq实现优先队列,按F值排序。
    对于每个扩展节点,检查是否越界或已经访问过。
    使用G值(步数*5)和H值计算F值,并加入优先队列。

  4. 输入输出处理:循环处理多个测试用例,每个测试用例根据起点和终点坐标,调用A*算法求解。

时间复杂度:

最坏情况下,骑士可能需要遍历整个1000x1000的棋盘,时间复杂度约为O(NlogN),其中N是棋盘的大小,logN来自优先队列操作。
卡码题目链接
题目文章讲解

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

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

相关文章

MOE论文汇总2

TASK-CUSTOMIZED MASKED AUTOENCODER VIA MIXTURE OF CLUSTER-CONDITIONAL Experts 这篇论文提出了一种新颖的自监督学习方法&#xff0c;名为“Mixture of Cluster-conditional Experts (MoCE)”&#xff0c;旨在解决传统Masked Autoencoder (MAE)在不同下游任务中可能遇到的负…

Linux基础3-基础工具4(git,冯诺依曼计算机体系结构)

上篇文章&#xff1a;Linux基础3-基础工具3&#xff08;make,makefile,gdb详解&#xff09;-CSDN博客 本章重点&#xff1a; 1. git简易使用 2. 冯诺依曼计算机体系结构介绍 一. git使用 1.1 什么是git? git是用于管理代码版本的一种工具&#xff0c;我们在如GitHub&#xf…

并发带来的对象一致性问题

多线程操作带来数据不一致情况分析&#xff0c;简单demo。 public class Object_IS {private Student_Object so new Student_Object("张三", 123);public static void main(String[] args) throws InterruptedException {Object_IS os new Object_IS();os.test1(…

利用语义搜索和混合查询策略提升RAG系统的准确性

人工智能咨询培训老师叶梓 转载标明出处 在构建基于大模型&#xff08;LLM&#xff09;的生成式问答系统&#xff08;Generative Q&A&#xff09;时&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;方法被广泛采用。RAG通过结合检索…

Leetcode—删除有序数组的重复项

题目描述 思路 思路&#xff1a;定义两个指针/变量&#xff0c;dst指向第一个位置&#xff0c;scr指向下一个位置&#xff0c;判断scr和dst位置的数据。 case1&#xff1a;相等&#xff0c;scr; case2: 不相等&#xff0c;dst,nums[dst]nums[scr],scr; 画图解释 定义两个指针…

基于SpringBoot+Vue+MySQL的社区医院管理系统

系统展示 系统背景 在当前医疗体系日益完善的背景下&#xff0c;社区医院作为基层医疗服务的重要一环&#xff0c;其管理效率和服务质量直接关系到居民的健康福祉。为了提升社区医院的管理水平&#xff0c;优化患者就医体验&#xff0c;我们设计了一套基于SpringBoot、Vue.js与…

09年408考研真题解析-计算机网络

[题34]在无噪声情况下&#xff0c;若某通信链路的带宽为3kHz&#xff0c;采用4个相位&#xff0c;每个相位具有4种振幅的QAM调制技术,则该通信链路的最大数据传输速率是&#xff08;B&#xff09; A.12 kbps B.24 kbps C.48 kbps D.96 kbps 解析&#xff…

主流的Java的webapi接口模板特点分析

Java 作为一种广泛应用于企业级开发的编程语言&#xff0c;其在 Web API 开发中具有重要的地位。随着 Java 生态系统的不断发展&#xff0c;市面上涌现了多种不同的 Web API 框架和设计模式。不同的 Web API 模板在设计上各有特点&#xff0c;适合不同类型的开发需求。本文将详…

从0-1 用AI做一个赚钱的小红书账号(不是广告不是广告)

大家好&#xff0c;我是胡广&#xff01;是不是被标题吸引过来的呢&#xff1f;是不是觉得自己天赋异禀&#xff0c;肯定是那万中无一的赚钱天才。哈哈哈&#xff0c;我告诉你&#xff0c;你我皆是牛马&#xff0c;不要老想着突然就成功了&#xff0c;一夜暴富了&#xff0c;瞬…

【Java 优选算法】双指针(下)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 有效三角形的个数 题目链接 解法 解法1:暴力枚举--->O(n^3) 解法2:利用单调性,使用双指针来解决---->O(n^2) 优化:对整个数组进行排序先固定最大数在最大数的左…

微服务_入门1

文章目录 一、 认识微服务二、 微服务演变2.1、 单体架构2.2、 分布式架构2.3、 微服务2.4、 微服务方案对比 三、 注册中心3.1、 Eureka3.2、 Nacos3.2.1、服务分级存储模型3.2.2、权重配置3.2.3、环境隔离 一、 认识微服务 二、 微服务演变 随着互联网行业的发展&#xff0c;…

Spark Streaming基础概论

1. 简介 1.1 什么是 Spark Streaming&#xff1f; Spark Streaming 是 Apache Spark 的一个扩展模块&#xff0c;专门用于处理实时数据流。它通过将数据流切分为一系列小批次&#xff08;微批次&#xff09;进行处理&#xff0c;使得开发者能够使用与批处理相同的 API 来处理…

【MRI基础】混叠伪影

基本概念 混叠&#xff08;aliasing&#xff09;&#xff0c;也称为环绕伪影(wrap around artifacts)&#xff0c;是一种常见的伪影&#xff0c;当视场 (FOV) 小于实际成像物体时&#xff0c;可能会在磁共振成像 (MRI) 中出现。空间定位由选定组织样本内的自旋频率决定。选定视…

正点原子阿尔法ARM开发板-IMX6ULL(六)——通过官方SDK完成实验

文章目录 一、引言1.1 cc.h1.2 main.c1.2 fsl_common.h、MCIMX6Y2.h、fsl_iomuxc.h1.3 对于宏定义能多个参数 其他 一、引言 在开发过程中&#xff0c;如果一个人来写寄存器、汇编等东西&#xff0c;会变得特别繁琐&#xff0c;好在官方NXP官方给出了SDK包&#xff0c; 1.1 c…

解决IDEA每次创建新项目时都要指定Maven仓库和Maven配置文件的问题

文章目录 0. 前言1. 打开新项目的设置2. 搜索 Maven 相关的配置3. 更改Maven主路径、配置文件、本地仓库4. 更改新项目的Maven配置后没生效 0. 前言 在 IDEA 中每次创建新项目时&#xff0c;使用的都是默认的 Maven 仓库和默认的配置文件&#xff0c;需要我们手动修改&#xf…

对称密码中的密钥是如何实现安全配送的?

对称密码在设计时就存在一个天然的缺陷&#xff0c;就是要求通信双方都要持有相同的密钥。确保密钥的安全传输和防止密钥泄露&#xff0c;往往比加密算法本身更为复杂和困难。一旦密钥被第三方获取&#xff0c;通信的安全性就会受到严重威胁&#xff0c;从而可能暴露敏感信息。…

网络协议全景:Linux环境下的TCP/IP、UDP

目录 1.UDP协议解析1.1.定义1.2.UDP报头1.3.特点1.4.缓冲区 2.TCP协议解析2.1.定义2.2.报头解析2.2.1.首部长度&#xff08;4位&#xff09;2.2.2.窗口大小2.2.3.确认应答机制2.2.4.6个标志位 2.3.超时重传机制2.4.三次握手四次挥手2.4.1.全/半连接队列2.4.2.listen2.4.3.TIME_…

Git rebase 的使用(结合图与案例)

目录 Git rebase 的使用Git rebase 概念Git rebase 原理rebase和merge的选择 Git rebase 的使用 在 Git 中整合来自不同分支的修改主要有两种方法&#xff1a;merge 以及 rebase Git rebase 概念 **rebase概念&#xff1a;**用来重新应用提交&#xff08;commits&#xff09…

指针式仪表识别

源码下载&#xff1a;小宅博客网 效果如下&#xff1a; 工程结构&#xff1a; 说明&#xff1a; 源码是针对下面这种刻度&#xff0c;并且单个指针的仪表的 如果是下面这种&#xff0c;刻度线被连接起来的&#xff0c;目前不支持转换成仪表单位&#xff0c;只能输出指针角度&…

操作系统名词_文件下载_反弹shell_1

目录 名词解释 Poc、EXP、Payload与shellcode 后门 木马、病毒 黑白盒测试 社会工程学、撞库 ATT&CK 应用实例 实用案例1&#xff1a;文件上传下载-解决无图形化&解决数据传输 实用案例2&#xff1a;反弹shell命令-解决数据回显&解决数据通讯 结合案例1&…