Floyd 算法

本题是经典的多源最短路问题.

Floyd 算法对边的权值正负没有要求,都可以处理

Floyd算法核心思想是动态规划。

例如我们再求节点1 到 节点9 的最短距离,用二维数组来表示即:grid[1][9],如果最短距离是10 ,那就是 grid[1][9] = 10。

那 节点1 到 节点9 的最短距离 是不是可以由 节点1 到节点5的最短距离 + 节点5到节点9的最短距离组成呢?

即 grid[1][9] = grid[1][5] + grid[5][9]

节点1 到节点5的最短距离 是不是可以有 节点1 到 节点3的最短距离 + 节点3 到 节点5 的最短距离组成呢?

即 grid[1][5] = grid[1][3] + grid[3][5]

以此类推,节点1 到 节点3的最短距离 可以由更小的区间组成。

那么这样我们是不是就找到了,子问题推导求出整体最优方案的递归关系呢。

这里我们用 grid数组来存图,那就把dp数组命名为 grid。

grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合中的一个节点为中间节点的最短距离为m

 这里的k不能单独指某个节点,k 一定要表示一个集合,即[1...k] ,表示节点1 到 节点k 一共k个节点的集合。

我们分两种情况:

  1. 节点i 到 节点j 的最短路径经过节点k
  2. 节点i 到 节点j 的最短路径不经过节点k

对于第一种情况,grid[i][j][k] = grid[i][k][k - 1] + grid[k][j][k - 1]

节点i 到 节点k 的最短距离 是不经过节点k,中间节点集合为[1...k-1],所以 表示为grid[i][k][k - 1]

节点k 到 节点j 的最短距离 也是不经过节点k,中间节点集合为[1...k-1],所以表示为 grid[k][j][k - 1]

第二种情况,grid[i][j][k] = grid[i][j][k - 1]

如果节点i 到 节点j的最短距离 不经过节点k,那么 中间节点集合[1...k-1],表示为 grid[i][j][k - 1]

因为我们是求最短路,对于这两种情况自然是取最小值。

即: grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])

grid[i][j][k] = m,表示 节点i 到 节点j 以[1...k] 集合为中间节点的最短距离为m。

刚开始初始化k 是不确定的。

例如题目中只是输入边(节点2 -> 节点6,权值为3),那么grid[2][6][k] = 3,k需要填什么呢?

把k 填成1,那如何上来就知道 节点2 经过节点1 到达节点6的最短距离是多少 呢。

所以 只能 把k 赋值为 0,本题 节点0 是无意义的,节点是从1 到 n。

这样我们在下一轮计算的时候,就可以根据 grid[i][j][0] 来计算 grid[i][j][1],此时的 grid[i][j][1] 就是 节点i 经过节点1 到达 节点j 的最小距离了。

遍历的顺序是从底向上 一层一层去遍历。

所以遍历k 的for循环一定是在最外面,这样才能一层一层去遍历。

kama97. 小明逛公园
题目描述

小明喜欢去公园散步,公园内布置了许多的景点,相互之间通过小路连接,小明希望在观看景点的同时,能够节省体力,走最短的路径。 

给定一个公园景点图,图中有 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 之间并没有道路。

1 <= N, M, Q <= 1000.

1 <= w <= 10000.

#include <bits/stdc++.h>
using namespace std;
int main()
{int n,m,p1,p2,val;cin>>n>>m;vector<vector<vector<int>>> grid(n+1,vector<vector<int>>(n+1,vector<int>(n+1,10001)));while(m--){cin>>p1>>p2>>val;grid[p1][p2][0] = val;//可以想象为一个三维的空间,我们只初始化空间的底层,后续遍历的时候从底层一层一层往上遍历。grid[p2][p1][0] = val;//双向图!!!}for(int k = 1;k<=n;k++)//注意这里先遍历k{for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){grid[i][j][k] = min(grid[i][j][k-1],grid[i][k][k-1]+grid[k][j][k-1]);}}}int q,start,end;cin>>q;while(q--){cin>>start>>end;if(grid[start][end][n]==10001)cout<<"-1"<<endl;else cout<<grid[start][end][n]<<endl;}
}

A * 算法

Astar 是一种 广搜的改良版。 有的是 Astar是 dijkstra 的改良版。

其实只是场景不同而已 我们在搜索最短路的时候, 如果是无权图(边的权值都是1) 那就用广搜,代码简洁,时间效率和 dijkstra 差不多 (具体要取决于图的稠密)

如果是有权图(边有不同的权值),优先考虑 dijkstra。

而 Astar 关键在于 启发式函数, 也就是 影响 广搜或者 dijkstra 从 容器(队列)里取元素的优先顺序。

大家可以发现 BFS 是没有目的性的 一圈一圈去搜索, 而 A * 是有方向性的去搜索

 启发式函数 要影响的就是队列里元素的排序

对队列里节点进行排序,就需要给每一个节点权值,如何计算权值呢?

每个节点的权值为F,给出公式为:F = G + H

G:起点达到目前遍历节点的距离

H:目前遍历的节点到达终点的距离

起点达到目前遍历节点的距离 + 目前遍历的节点到达终点的距离 就是起点到达终点的距离。

题的图是无权网格状,在计算两点距离通常有如下三种计算方式:

  1. 曼哈顿距离,计算方式: d = abs(x1-x2)+abs(y1-y2)
  2. 欧氏距离(欧拉距离) ,计算方式:d = sqrt( (x1-x2)^2 + (y1-y2)^2 )
  3. 切比雪夫距离,计算方式:d = max(abs(x1 - x2), abs(y1 - y2))

x1, x2 为起点坐标,y1, y2 为终点坐标 ,abs 为求绝对值,sqrt 为求开根号,

选择哪一种距离计算方式 也会导致 A * 算法的结果不同。

本题,采用欧拉距离才能最大程度体现 点与点之间的距离。

相对了 普通BFS,A * 算法只从 队列里取出 距离终点最近的节点。

那么问题来了,A * 在一次路径搜索中,大量不需要访问的节点都在队列里,会造成空间的过度消耗。

IDA * 算法 对这一空间增长问题进行了优化,关于 IDA * 算法,本篇不再做讲解,感兴趣的录友可以自行找资料学习。

另外还有一种场景 是 A * 解决不了的。

如果题目中,给出 多个可能的目标,然后在这多个目标中 选择最近的目标,这种 A * 就不擅长了, A * 只擅长给出明确的目标 然后找到最短路径。

如果是多个目标找最近目标(特别是潜在目标数量很多的时候),可以考虑 Dijkstra ,BFS 或者 Floyd。

127. 骑士的攻击
题目描述

在象棋中,马和象的移动规则分别是“马走日”和“象走田”。现给定骑士的起始坐标和目标坐标,要求根据骑士的移动规则,计算从起点到达目标点所需的最短步数。

棋盘大小 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
提示信息

骑士移动规则如图,红色是起始位置,黄色是骑士可以走的地方。

#include <bits/stdc++.h>
using namespace std;
int dir[8][2] = {-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2};
int moves[1001][1001];
int b1, b2;
struct Knight
{int x,y;int f,g,h; //f = g + h;  g为从起点到当前遍历节点的消耗,h为当前遍历节点到终点的“预计“消耗bool operator < (const Knight& k) const{return k.f < f;//后续的priority_queue会根据这个来找出f最小的。} 
};
priority_queue<Knight> que;
int calDistance(const Knight& k)
{return (k.x-b1)*(k.x-b1)+(k.y-b2)*(k.y-b2);
}
void astar(const Knight& k)
{Knight cur,next;que.push(k);while(!que.empty()){cur = que.top();que.pop();if(cur.x == b1 && cur.y == b2)break;for(int i = 0;i<8;i++){next.x = cur.x + dir[i][0];next.y = cur.y + dir[i][1];if(next.x<1||next.x>1000||next.y<1||next.y>1000)continue;if(!moves[next.x][next.y]){moves[next.x][next.y] = moves[cur.x][cur.y] +1;next.g = cur.g + 5;//马走日,2*2+1*1.next.h = calDistance(next);next.f = next.g + next.h;que.push(next);}}}
}
int main()
{int n,a1,a2;cin>>n;while(n--){cin>>a1>>a2>>b1>>b2;memset(moves,0,sizeof(moves));Knight start;start.x = a1;start.y = a2;start.g = 0;start.h = calDistance(start);start.f = start.g + start.h;astar(start);while(!que.empty())que.pop();cout<<moves[b1][b2]<<endl;}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【软考论文】论可观测性架构技术的应用

&#x1f381; 考高级架构师的小伙伴注意了&#xff01;&#x1f4e2; 软考架构论文示例 2025年11月软考架构论文预测&#x1f44d; 一、历年论文题目 无&#xff01;&#xff01;&#xff01; 二、考情分析 “可观测性技术”这一论题&#xff0c;目前在高级架构师与高级系统分…

软件测试:测试分类(一)

常用测试分类1.功能测试&#xff08;人对功能的确定&#xff0c;保证某个功能可以正常进行&#xff09;如验证你输入正确的手机号码和密码是否登录成功。手机号码不存在是否有提示&#xff0c;密码不正确是否有提示等2.自动化测试&#xff08;如jmeter&#xff0c;属于黑盒测试…

BigFoot (Method Raid Tools)[MRT] (Event Alert Mod)[EAM]

检查法术技能ID&#xff0c;需要EAM命令&#xff0c;所以要先安装EAM BigFoot EventAlertMod lua-CSDN博客 /eam lookup 冰封之韧 同时我们发现一个糟糕的问题&#xff0c;为什么会有这么多ID呢&#xff0c;默认第一个 还有一种法子就是让别人开了技能告诉你ID&#xff0c;最…

【Scrapy-Redis】分布式爬虫实战(非常详细)

一、概要 1.分布式爬虫概念 分布式爬虫是一种利用多台机器协同工作的网络爬虫系统&#xff0c;通过任务分解、并行处理和资源共享&#xff0c;高效抓取并处理海量网页数据。其核心在于将爬取任务分配到不同节点&#xff0c;避免单点性能瓶颈&#xff0c;同时支持动态扩展和容错…

基于51单片机智能化交通红绿灯堵车流量红外设计

1 系统功能介绍 本设计题目为 基于51单片机智能化交通红绿灯堵车流量红外设计&#xff0c;主要用于十字路口交通信号智能控制&#xff0c;通过红外避障检测车流量&#xff0c;自动调节红绿灯时间&#xff0c;缓解拥堵。该系统由单片机、LED灯、红外避障传感器、LCD1602液晶显示…

VsCode 上的Opencv(C++)环境配置(Linux)

1.下载Opencv1.新建文件demo_cpp,在demo_cpp中新建third_parties文件2.OPENCV官网下载OpenCV-4.12.03.将下载好的opencv-4.12.0.zip压缩包在third_parties中解压,//以下均无特殊说明,均在vscode里的TERMINAL中输入 sudo apt-get install unzip//用于解压.zip文件 cd third_part…

sql xml模板

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace"com.example.mapper.UserMapper&quo…

docker在自定义网络中安装ElasticSearch和Kibana

创建自定义网络 创建一个名为 es-net 的桥接网络。这将作为 Elasticsearch 和 Kibana 的私有通信通道。 # 创建网络 docker network create es-net # 查看网络是否创建成功 docker network ls启动 Elasticsearch 容器 安装命令 docker run -d \--name elasticsearch \--net…

基于51单片机射频RFID停车刷卡计时收费系统设计

1 系统功能介绍 本设计题目为 基于51单片机射频RFID停车刷卡计时收费系统设计&#xff0c;旨在实现停车场车辆的刷卡计时和收费管理。系统通过单片机控制&#xff0c;结合 RFID 射频识别技术、LCD1602 显示以及蜂鸣器报警&#xff0c;实现停车时间的智能计时、累加及超时提醒功…

Netty源码—性能优化和设计模式

1.Netty的两大性能优化工具 (1)FastThreadLocal FastThreadLocal的作用与ThreadLocal相当&#xff0c;但比ThreadLocal更快。ThreadLocal的作用是多线程访问同一变量时能够通过线程本地化的方式避免多线程竞争、实现线程隔离。 Netty的FastThreadLocal重新实现了JDK的ThreadLoc…

Linux网络设备分析

🐧 Linux 网络设备驱动深入分析 本文将详细分析 Linux 网络设备驱动的工作原理、实现机制和代码框架,并通过一个虚拟网卡实例展示其实现,最后介绍常用的工具和调试手段。 1️⃣ Linux 网络设备驱动概述 Linux 网络设备驱动是内核中负责管理网络硬件(如以太网卡、Wi-Fi …

计算机视觉:从 “看见” 到 “理解”,解锁机器感知世界的密码

早上醒来&#xff0c;你拿起手机&#xff0c;人脸识别瞬间解锁屏幕&#xff1b;开车上班时&#xff0c;车载系统通过摄像头实时识别车道线&#xff0c;提醒你不要偏离&#xff1b;去医院做检查&#xff0c;医生用 AI 辅助的医学影像系统快速定位肺部微小结节&#xff1b;逛超市…

深入了解linux系统—— 线程封装

C11线程库 C11也提供了对应的线程库&#xff0c;在头文件<thread>中&#xff1b;C11将其封装成thread类&#xff0c;通过类实例化出对象&#xff0c;调用类内成员方法进行线程控制。 #include <iostream> #include <thread> #include <unistd.h> using…

安全防御-SCDN如何保护网站安全

随着互联网的快速发展&#xff0c;越来越多的企业依赖在线服务来运行其核心业务。与此同时&#xff0c;网络攻击的频率和复杂性也在不断增加&#xff0c;恶意流量成为许多企业头疼的问题。为了有效地提高网站的安全性和稳定性&#xff0c;德迅云安全加速SCDN被许多用户关注。今…

运筹优化(OR)-在机器学习(ML)浪潮中何去何从?

在如今机器学习的浪潮中&#xff0c;机器学习相关的岗位日益增多&#xff0c;而运筹优化的岗位却相对较少。这是今年我秋招过程中看到的现象。企业越来越希望候选人不仅能建模求解&#xff0c;还能理解如何用数据驱动优化。需要我们有一个完整的技术栈。那么我们就来看看OR与ML…

GitHub Copilot 在 VS Code 上的终极中文指南:从安装到高阶玩法

GitHub Copilot 在 VS Code 上的终极中文指南&#xff1a;从安装到高阶玩法 前言 GitHub Copilot 作为 AI 编程助手&#xff0c;正在彻底改变开发者的编码体验。本文将针对中文开发者&#xff0c;深度解析如何在 VS Code 中高效使用 Copilot&#xff0c;涵盖基础设置、中文优化…

安全测试、web探测、httpx

&#x1f4a2; 简介 httpx 是一个快速且多用途的HTTP工具包&#xff0c;允许使用retryablehttp库运行多个探测器。它旨在通过增加线程数量来保持结果的可靠性。 功能 &#x1f92a; 发送 GET、POST、PUT、DELETE 等 HTTP 请求支持流式传输支持重定向支持身份验证支持代理支持 …

CNN 中 3×3 卷积核等设计背后的底层逻辑

为什么卷积核爱用 33&#xff1f;CNN 设计 “约定俗成” 的底层逻辑 做深度学习的同学&#xff0c;对 CNN 里 33 卷积核、最大池化、BN 层这些设计肯定不陌生&#xff0c;但你有没有想过&#xff1a;为啥卷积核总选 33&#xff1f;池化层为啥默认最大池化&#xff1f;BN 层又是…

税务岗位职场能力解析与提升路径规划

税务岗位作为企业运营的核心环节之一&#xff0c;对从业者的专业能力与综合素质要求极高。从基础税务核算到战略税务筹划&#xff0c;职场能力的提升需要系统化的路径规划。以下从核心能力、阶段化提升路径及证书价值三个维度展开分析。核心能力体系构建专业税务能力是基础&…

MySQL 索引:结构、对比与操作实践指南

MySQL系列 文章目录MySQL系列前言案例一、认识MySQL与磁盘1.1 MySQL与存储1.2 MySQL 与磁盘交互基本单位二、 MySQL 数据交互核心&#xff1a;BufferPool 与 IO 优化机制三、索引的理解3.1 测试案例3.2 page3.3 页目录3.3 对比其他结构四、聚簇索引 VS 非聚簇索引五、索引操作5…