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

news2024/11/16 4:51:20

代码随想录训练营 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 和边数 m
    n, m = map(int, input().split())

    # 初始化二维数组 grid,存储最短路径,初始值为无穷大
    grid = [[max_int] * (n + 1) for _ in range(n + 1)]
    
    # 自己到自己的最短路径为 0
    for 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值,每次移动的代价是5
                    h = heuristic(nx, ny, b1, b2)  # 计算启发式估计值H
                    f = 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)  # 如果起点和终点相同,步数为0
        else:
            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.coloradmin.cn/o/2144096.html

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

相关文章

C++速通LeetCode中等第3题-字母异位词分组

双指针法&#xff1a;两个指针分别指向左右边界&#xff0c;记录最大面积&#xff0c;由于面积由短板决定&#xff0c;两个指针中较短的短指针向内移动一格&#xff0c;再次记录最大面积&#xff0c; 直到两指针相遇&#xff0c;得出答案。 class Solution { public:int maxAr…

PyQt / PySide + Pywin32 + ctypes 自定义标题栏窗口 + 完全还原 Windows 原生窗口边框特效项目

项目地址&#xff1a; GitHub - github201014/PyQt-NativeWindow: A class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypesA class of window include nativeEvent, use PySide or PyQt and Pywin32 and ctypes - github201014/PyQt-NativeWindow…

切换淘宝最新npm镜像源

文章目录 一、前言二、切换淘宝最新npm镜像源2.1 查询最新镜像源2.2 两种方式切换npm镜像源2.2.1 通过npm配置2.2.1 通过cnpm配置 三、总结 一、前言 NPM&#xff08;Node Package Manager&#xff09;&#xff0c;是NodeJs的模块依赖管理工具&#xff0c;用于nodejs模块的安装…

java多线程模拟多个售票员从同一个票池售票

程序功能 这段代码模拟了多个售票员从一个有限的票池中售票的过程。主要功能如下&#xff1a; 票池共有50张票&#xff0c;多个售票员&#xff08;线程&#xff09;并发进行售票。 使用同步机制确保线程安全&#xff0c;避免多个售票员同时出售同一张票。 每个售票员不断检查票…

5.内容创作的未来:ChatGPT如何辅助写作(5/10)

引言 在信息爆炸的时代&#xff0c;内容创作已成为连接品牌与受众、传递信息与知识、以及塑造文化与观念的重要手段。随着数字媒体的兴起&#xff0c;内容创作的需求日益增长&#xff0c;对创作者的写作速度和质量提出了更高的要求。人工智能&#xff08;AI&#xff09;技术的…

PHP全程可视化防伪溯源一体化管理系统小程序源码

全程可视化&#xff0c;防伪溯源新篇章 —— 揭秘一体化管理系统的力量 &#x1f50d; 开篇&#xff1a;透视未来&#xff0c;从源头到终端的安心之旅 在这个信息透明化时代&#xff0c;每一件商品都承载着消费者的信任与期待。而“全程可视化防伪溯源一体化管理系统”&#x…

【网络安全 | 代码审计】PHP无参数RCE

未经许可,不得转载。 文章目录 无参数RCE代码审计1、利用Session ID实现无参数RCE2、利用get_defined_vars ()函数实现无参数RCE3、利用getallheaders()实现无参数RCE4、利用getenv()实现无参数RCE5、利用scandir()实现无参数RCE靶场实例无参数RCE 一般情况下,RCE需要通过传…

Nuxt3部署遇到的问题归纳

fetch Headers is not a constructor 和 _fetch is not a function 这两个问题&#xff0c;本质上都是fetch在服务器上无法正常使用的问题&#xff0c;需要检查本地node版本与线上服务器node版本是否一致。否则在依赖安装上会产生依赖版本差异导致应用无法正常运行。 以下是wi…

若依-原理

1.代码生成器 1.1源码分析 代码生成器分为两个部分&#xff1a; 第一部分涉及将业务表结构导入到系统中 第二部分是点击生成按钮&#xff0c;系统将根据表结构生成相应的前后端代码&#xff0c;并提供下载。 1.表结构说明 gen_table&#xff1a;存储业务表的基本信息 &am…

事件循环event loop入门(基于ESP-IDF)

主要参考资料&#xff1a; 事件循环库: https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-reference/system/esp_event.html Event Loop 大白话版: https://www.bilibili.com/video/BV1FD4y1j79J/?spm_id_from333.999.0.0&vd_sourcedd284033cd0c4d1f3…

盘点常见网络安全术语(建议收藏)

1、黑帽 为非法目的进行黑客攻击的人&#xff0c;通常是为了经济利益。他们进入安全网络以销毁&#xff0c;赎回&#xff0c;修改或窃取数据&#xff0c;或使网络无法用于授权用户。这个名字来源于这样一个事实&#xff1a;老式的黑白西部电影中的恶棍很容易被电影观众识别&…

在linux用docker部署MySQL失败

Unable to find image mysql:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp 128.121.243.107:443: i/o timeout. See docker run --help. 从网上找解决问题一直说是镜像问题&#xff0c;我原来的镜像是从自…

8-----手机机型维修工具助手 功能较全 涵盖解锁 刷机 修复等选项 维修推荐

上图是一款功能较全的维修加密狗。目前可以无限制 任何人使用。看图片可以了解其中涵盖刷机 解锁 修复分区 查看短接图 安装驱动 修复基带等等选项。而且其中有针对各个机型型号的对应功能操作。以及一些rec5.0相关的操作选项。 通过此博文了解 ★★★★★此工具涵盖的一些…

优秀项目经理需必备的四个项目管理最佳技术

项目经理在项目管理过程中&#xff0c;需要具备多种管理思维以确保项目的顺利进行和成功交付。项目经理要有效地管理好项目&#xff0c;确保项目按时、按质、按预算完成&#xff0c;需要特别关注以下四个方面&#xff1a; 1. 明确项目目标与范围 设定清晰目标&#xff1a;与项目…

C++竞赛初阶L1-15-第六单元-多维数组(34~35课)557: T456507 图像旋转

题目内容 输入一个 n 行 m 列的黑白图像&#xff0c;将它顺时针旋转 90 度后输出。 输入格式 第一行包含两个整数 n 和 m&#xff0c;表示图像包含像素点的行数和列数。1≤n≤100&#xff0c;1≤m≤100。 接下来 n 行&#xff0c;每行 m 个整数&#xff0c;表示图像的每个像…

OpenCV与AI深度学习 | 实战!利用多模态大模型生成绘本

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;实战&#xff01;利用多模态大模型生成绘本【文末送书】 &#x1f680; 引言 在数字时代&#xff0c;技术与创意的结合不断刷新我们的世界观。…

25届计算机毕业设计选题推荐-图书馆智能选座系统

&#x1f496;&#x1f525;作者主页&#xff1a;毕设木哥 精彩专栏推荐订阅&#xff1a;在 下方专栏&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; Java实战项目 文章目录 Java实战项目 一、图书馆智能选座系统…

某思CMS V10存在SQL注入漏洞

Fofa: product"魅思-视频管理系统" 框架:ThinkPHP 5,6 1 漏洞分析&复现 位于 /controller/Api.php 控制器中的getOrderStatus 方法POST传入&#xff0c;然后直接拼接了 orderSn 变量到 where 查询中&#xff0c;导致漏洞产生. /** * 查询订单支付状态 */ pub…

猎板PCB大讲堂——全球电子产品中PCB阻燃性能的法规与标准概述

今天猎板PCB来说说PCB的板材的阻燃性&#xff01;猎板发现有些PCB平台在售的板厂大多为非阻燃系列&#xff0c;而在许多国家和地区&#xff0c;电子产品及其组件&#xff0c;包括印刷电路板&#xff08;PCB&#xff09;&#xff0c;都必须遵守严格的安全标准&#xff0c;其中包…

项目测试用例:

项目概述 该项目是一款网上点餐系统&#xff0c;满足普通商家和普通用户的基本需求&#xff0c;主要有两大功能模块&#xff0c;分别是管理员模块&#xff08;商家端&#xff09;和用户模块&#xff08;客户端&#xff09;。系统供管理员登录和普通用户&#xff0c;登录进去会有…