最短路模型——AcWing 188. 武士风度的牛

最短路模型

定义

最短路模型是图论中的一个经典问题,旨在寻找从图中一个顶点到另一个顶点的路径,使得这条路径上的边(或边的权重)之和最小。这一模型在许多实际问题中有着广泛的应用,比如网络路由、地图导航、物流配送等场景。

在图论中,最短路问题通常形式化为在一个加权图 G=(V,E)G=(V,E) 中寻找两个顶点 uu 和 vv 之间的最短路径,其中 VV 是顶点集,EE 是边集,每条边 e \in Ee∈E 都有一个非负权重 w(e)w(e)。目标是找到一条从 uu 到 vv 的路径,使得路径上所有边的权重之和最小。

运用情况

  1. 网络路由:在互联网中,数据包需要通过最少的延迟或最低的成本从源节点传输到目的节点,这可以看作是一个最短路径问题。
  2. 地图导航:为司机或行人提供从起点到终点的最快或距离最短的路线。
  3. 物流与供应链管理:确定货物从仓库到客户或从供应商到工厂的最优运输路线,以减少运输成本和时间。
  4. 电路设计:在集成电路设计中,选择信号传递的最短路径以减少延迟和功耗。
  5. 社交网络分析:分析两个人之间关系链的最短路径,用于推荐系统或影响力传播分析。

注意事项

  1. 负权重边:如果图中存在负权重边,则不能直接使用某些算法如Dijkstra算法,而应考虑Bellman-Ford算法或Floyd-Warshall算法,因为它们能处理负权。
  2. 环路检测:在有负权重边的情况下,需要检查是否存在负权重环,因为这样的环路会导致无限减小路径长度,从而使问题无解。
  3. 稠密图与稀疏图:根据图的密度选择合适的算法。例如,Floyd-Warshall算法适用于稠密图,而Dijkstra或A*算法更适合稀疏图。
  4. 多源或多目标:当需要计算多个源点到单个目标或多个目标的最短路径时,可能需要对算法进行适当调整或多次调用。

解题思路

  1. 理解问题:首先明确问题是否为单源最短路径还是多源最短路径,图中是否存在负权重边。
  2. 选择算法:根据问题的具体情况选择合适的算法。常见的算法有Dijkstra算法(适用于无负权的单源最短路径)、Bellman-Ford算法(可处理负权重但无负权重环)、Floyd-Warshall算法(解决所有顶点对之间的最短路径,适合稠密图)。
  3. 实现与优化:实现所选算法,并考虑如何优化,比如使用优先队列优化Dijkstra算法,或在特定情况下利用预处理技巧减少计算量。
  4. 验证结果:检查计算出的路径是否确实是最短的,并确保没有违反任何先决条件,如负权重环的存在。

AcWing 188. 武士风度的牛

题目描述

AcWing 188. 武士风度的牛 - AcWing

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 155, M = N * N;

int n, m;
char g[N][N];
PII q[M];
int dist[N][N];

int bfs()
{
    int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};
    int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};
    int sx, sy;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'K')
                sx = i, sy = j;

    int hh = 0, tt = 0;
    q[0] = {sx, sy};

    memset(dist, -1, sizeof dist);
    dist[sx][sy] = 0;

    while (hh <= tt)
    {
        PII t = q[hh ++ ];

        for (int i = 0; i < 8; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (g[a][b] == '*') continue;
            if (dist[a][b] != -1) continue;
            if (g[a][b] == 'H') return dist[t.x][t.y] + 1;

            dist[a][b] = dist[t.x][t.y] + 1;
            q[ ++ tt] = {a, b};
        }
    }

    return -1;
}

int main()
{
    cin >> m >> n;
    for (int i = 0; i < n; i ++ ) cin >> g[i];

    cout << bfs() << endl;

    return 0;
}

代码思路

  1. 包含文件和宏定义:

    • 包含了 <cstring><iostream> 和 <algorithm> 头文件,分别用于字符串处理、输入输出和算法操作。
    • 定义了一个宏 N 作为最大地图大小,并定义了类型别名 PII 为 pair<int, int>,用于存储坐标。
    • 使用 #define x first 和 #define y second 来简化 pair 对象的访问。
  2. 变量声明和初始化:

    • 声明了 n 和 m 分别代表地图的行数和列数,二维字符数组 g 存储地图信息,q 作为队列存储待访问的坐标,dist 数组记录每个位置到起点的最短距离。
    • 通过 memset 函数将 dist 数组初始化为 -1,表示未访问过。
  3. 核心函数 bfs():

    • 首先,通过双层循环遍历地图,找到起始位置 'K' 的坐标 (sx, sy)
    • 初始化队列 q,并将起始位置入队。
    • 进行广度优先搜索,定义了变量 hh 和 tt 作为队列的头尾指针,并用数组 dx 和 dy 来表示马可能的八个移动方向。
    • 在 BFS 循环中,每次从队列头部取出一个坐标,遍历其八个可能的下一个位置,检查这些位置是否越界、是否有障碍物('*')或是否已经访问过。若新位置有效且未访问,则更新该位置的最短距离,并将其加入队列。
    • 如果在搜索过程中遇到草('H'),立即返回当前的最短距离加一(因为起始点的初始距离为0)。
    • 若循环结束仍未找到草,则返回 -1 表示无解(根据题目描述,这种情况实际上不会发生)。
  4. 主函数 main():读取地图的列数 m 和行数 n,然后逐行读取地图信息。调用 bfs() 函数计算并输出最短跳跃次数。

改进思路

  1. 代码注释:添加详细的注释,特别是对于关键变量、数组含义、函数功能等进行说明,提高代码的可读性和维护性。

  2. 命名规范:变量命名可以更加直观,例如将 sx, sy 改为 startX, startY,将 hh, tt 改为 head, tail,以增加代码的自解释性。

  3. 宏定义优化:考虑到使用 #define x first 和 #define y second 可能导致的命名冲突和阅读困难,可以考虑直接在代码中使用 first 和 second,或者在BFS函数内部临时定义辅助函数来访问pair的元素。

  4. 避免全局变量:尽量减少全局变量的使用,可以将 nmgqdist 等变量作为 bfs 函数的参数传入,以减少不同部分间的耦合度。

  5. 边界检查和错误处理:虽然题目保证有解,但在实际应用中,增加对输入数据的校验(如检查地图尺寸是否合理,起点和终点是否存在等)可以提高程序的健壮性。

  6. 内存使用优化:当地图规模非常大时,可以考虑使用压缩存储或动态分配内存来减少空间消耗,例如只对访问过的节点分配dist数组的空间。

  7. 代码结构清晰化:将BFS逻辑拆分成几个小函数,如初始化队列、拓展节点等,可以让代码逻辑更清晰,便于阅读和维护。

  8. 使用标准库函数或STL容器:考虑使用std::queue代替原始数组实现队列,这样可以利用STL容器的便利性,减少手动管理数组指针的复杂度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI绘画-Stable Diffusion 原理介绍及使用

引言 好像很多朋友对AI绘图有兴趣&#xff0c;AI绘画背后&#xff0c;依旧是大模型的训练。但绘图类AI对计算机显卡有较高要求。建议先了解基本原理及如何使用&#xff0c;在看看如何实现自己垂直行业的绘图AI逻辑。或者作为使用者&#xff0c;调用已有的server接口。 首先需…

Advanced slides插件无法预览幻灯片

advanced-slides的官方地址&#xff1a; MSzturc/obsidian-advanced-slides: Create markdown-based reveal.js presentations in Obsidian (github.com) 官方教程和文档&#xff1a; Advanced Slides Documentation (mszturc.github.io) 中文版也有博客翻译了&#xff1a;Ob…

[数据集][目标检测]桥梁检测数据集VOC+YOLO格式1116张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1116 标注数量(xml文件个数)&#xff1a;1116 标注数量(txt文件个数)&#xff1a;1116 标注…

51单片机第21步_将TIM0用作两个8位定时器同时将TIM1用作波特率发生器

本章重点讲解将TIM0用作两个8位定时器&#xff0c;同时将TIM1用作波特率发生器。 当定时器T0在方式3时&#xff0c;T1不能产生中断&#xff0c;但可以正常工作在方式0、1、2下&#xff0c;大多数情况下&#xff0c;T1将用作串口的波特率发生器。 1、定时器0工作在模式3框图&a…

【基础篇】第4章 Elasticsearch 查询与过滤

在Elasticsearch的世界里&#xff0c;高效地从海量数据中检索出所需信息是其核心价值所在。本章将深入解析查询与过滤的机制&#xff0c;从基础查询到复合查询&#xff0c;再到全文搜索与分析器的定制&#xff0c;为你揭开数据检索的神秘面纱。 4.1 基本查询 4.1.1 Match查询…

从手工作坊到智能工厂:APS与MES的升级之路

一、APS&#xff1a;制造业的中枢 APS&#xff08;AdvancedPlanningandScheduling&#xff09;&#xff0c;堪称制造业的数据接收和处理中枢&#xff0c;其借助前沿的算法与缜密的逻辑构建排程模型&#xff0c;全方位综合考量市场的多元需求、工厂的实际产能、物料的储备情况、…

Sentinel 采用的是什么限流算法?

引言&#xff1a;Sentinel 是一款由阿里巴巴开源的流量控制组件&#xff0c;提供了多种流控规则和限流算法&#xff0c;能够有效保护服务不被过载&#xff0c;同时实现服务的稳定运行。本文将深入探讨 Sentinel 所采用的主要限流算法&#xff0c;包括固定窗口计数器、滑动窗口计…

从0开始建SMARTFORMS表格

一、简介步骤 1、设置纸张的大小&#xff08;页格式&#xff09; 2、设置字体大小&#xff08;样式&#xff09; 3、设置表格模板 二、详细操作步骤 1、设置页格式 事务码&#xff1a;SPAD 参考操作&#xff1a;SAP Smartforms页格式创建与使用_sap 页格式-CSDN博客 SA…

【Altium】AD-焊盘介绍

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 介绍PCB设计工具中焊盘的组成 2、 知识点 为元件创建封装时&#xff0c;焊盘都是不可获取的部分&#xff0c;一个完整的焊盘&#xff0c;包含了哪些部分&#xff0c;各自又是什么作用。 3、软硬件环境 1&#xff…

深度学习 --- stanford cs231学习笔记六(训练神经网络之权重的初始化与批归一化)

权重矩阵的初始化与批归一化 3&#xff0c;权重矩阵的初始化 深度学习所学习的重点就是要根据损失函数训练权重矩阵中的系数。即便如此&#xff0c;权重函数也不能为空&#xff0c;总是需要初始化为某个值。 3&#xff0c;1 全都初始化为同一个常数可以吗&#xff1f; 首先要简…

英飞凌TC3xx之DMA工作原理及应用实例

英飞凌TC3xx之DMA工作原理及应用实例 1 DMA的架构2 必要的术语解释3 DMA请求3.1 DMA软件请求3.2 DMA硬件请求3.3 DMA 菊花链请求3.4 DMA自动启动请求3.5 总结4 小结DMA是直接存储访问Direct Memory Access的简称。它的唯一职能就是在不需要CPU参与的情况下,将数据从源地址搬运…

go Channel原理 (二)

Channel 设计原理 不要通过共享内存的方式进行通信&#xff0c;而是应该通过通信的方式共享内存。 在主流编程语言中&#xff0c;多个线程传递数据的方式一般都是共享内存。 Go 可以使用共享内存加互斥锁进行通信&#xff0c;同时也提供了一种不同的并发模型&#xff0c;即通…

复兴社:凝聚多方力量,共促乡村繁荣

复兴社自成立以来&#xff0c;始终肩负着推动全国经济发展、实现共同富裕的重任。乡村振兴作为实现这一目标的重要途径之一&#xff0c;一直是复兴社的工作重点。在李忠平会长的领导下&#xff0c;复兴社通过联合政府、企业和社会各界的资源&#xff0c;共同推进乡村振兴&#…

基于STM32的智能门锁控制系统

目录 引言环境准备智能门锁控制系统基础代码实现&#xff1a;实现智能门锁控制系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;门锁管理与优化问题解决方案与优化收尾与总结 1. 引言 智能门锁控制系统通过使用STM32嵌…

Is ChatGPT a Good Personality Recognizer? A Preliminary Study?

ChatGPT是一个很好的人格识别者吗&#xff1f;初步调研 摘要1 介绍2 背景和相关工作3 实验3.1 数据集3.2 提示策略3.3 基线3.4 评估指标3.5 实现细节3.6 Overall Performance (RQ1)3.7 ChatGPT在人格识别上的公平性 (RQ2)3.8 ChatGPT对下游任务的人格识别能力&#xff08;RQ3&a…

Java 面试指南合集

JVM 篇 线程篇 springBoot篇 SpringCloud篇 待更新 黑夜无论怎样悠长&#xff0c;白昼总会到来。 此文会一直更新哈 如果你希望成功&#xff0c;当以恒心为良友&#xff0c;以经验为参谋&#xff0c;以当心为兄弟&#xff0c;以希望为哨兵。

行业分析---造车新势力之极氪汽车

1 前言 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 《行业分析-…

绘图黑系配色

随便看了几篇小论文&#xff0c;里面的黑配色挺喜欢的&#xff0c;虽然平时SCI系配色用的多&#xff0c;但看到纯黑配色与黑加蓝配色&#xff0c;那就是我最心上的最优style。

【JVM】JVM 内存结构

程序计数器 Cpu 要不停的切换执行线程&#xff0c;所以在切换回同一个线程的时候要知道程序执行到哪了&#xff0c;程序计数器&#xff08;PC 计数器&#xff09;&#xff0c;用来存储指向下一条指令的地址&#xff0c;也就是将要执行的代码。 程序的分支、循环、跳转、异常处…

【论文解读】大模型的有效探索

一、简要介绍 论文提出的证据表明&#xff0c;通过有效地探索收集人类反馈以改进大型语言模型有实质性的好处。在论文的实验中&#xff0c;一个代理依次生成查询&#xff0c;同时拟合一个奖励模型的反馈收到。论文的最佳性能代理使用双汤普森抽样生成查询&#xff0c;其不确定性…