当前位置: 首页 > news >正文

【基础算法】多源 BFS

文章目录

  • 上文链接
  • 一、多源 BFS
    • 1. 单源最短路 vs 多源最短路
    • 2. 解决方案
  • 二、OJ 练习
    • 1. 矩阵距离 ⭐⭐
      • (1) 解题思路
      • (2) 代码实现
    • 2. 刺杀大使 ⭐⭐⭐
      • (1) 解题思路
      • (2) 代码实现

上文链接

  • BFS

一、多源 BFS

1. 单源最短路 vs 多源最短路

  • 当问题中只存在一个起点时,这时的最短路问题就是单源最短路问题。

  • 当问题中存在多个起点而不是单一起点时,这时的最短路问题就是多源最短路问题。


2. 解决方案

多源 BFS 多源最短路问题的边权都为 1 时,此时就可以用多源 BFS 来解决。

具体来说,多源 BFS:

  • 初始化的时候,把所有的源点都加入到队列里面;

  • 然后正常执行 BFS 的逻辑即可。也就是初始化的时候,比普通的 BFS 多加入几个起点。


二、OJ 练习

1. 矩阵距离 ⭐⭐

【题目链接】

矩阵距离

image-20250829192531460

(1) 解题思路

如果针对每一个 0,我们都直接去找最近的 1,我们需要对所有的 0 都来一次 BFS,这个时间复杂度是接受不了的。

但是我们如果反着来想,我们从每一个 1 开始向外扩展(即初始时把每一个 1 都加入到队列中),每遍历到一个 0 就更新一下最短距离。这样仅需一次 BFS,就可以把所有点距离的最短距离更新出来。这种思想就是正难则反


(2) 代码实现

#include<iostream>
#include<queue>using namespace std;typedef pair<int, int> PII;
queue<PII> q;
const int N = 1010;
char st[N][N];  // 读入的矩阵
int dist[N][N];  // 输出的矩阵,标记每一个位置的距离
int n, m;int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};void bfs()
{int step = 0;while(!q.empty()){int sz = q.size();step++;while(sz--){int r = q.front().first;int c = q.front().second;q.pop();for(int i = 0; i < 4; i++){int rr = r + dx[i];int cc = c + dy[i];if(rr > 0 && rr <= n && cc > 0 && cc <= m && st[rr][cc] == '0'){q.push({rr, cc});st[rr][cc] = '1';dist[rr][cc] = step;}}}}
}int main()
{cin >> n >> m;for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){cin >> st[i][j];// 多源 BFSif(st[i][j] == '1') q.push({i, j});  // 把所有 1 位置加入到队列}}bfs();for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){cout << dist[i][j] << " ";}cout << endl;}return 0;
}

2. 刺杀大使 ⭐⭐⭐

【题目链接】

P1902 刺杀大使 - 洛谷

【题目描述】

某组织正在策划一起对某大使的刺杀行动。他们来到了使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前的防御迷阵。

迷阵由 n × m n\times m n×m 个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第 n n n 行的 m m m 个房间里有 m m m 个机关,这些机关必须全部打开才可以进入大使馆。而第 1 1 1 行的 m m m 个房间有 m m m 扇向外打开的门,是迷阵的入口。除了第 1 1 1 行和第 n n n 行的房间外,每个房间都被使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第 i i i 行第 j j j 列 造成的伤害值为 p i , j p_{i,j} pi,j(第 1 1 1 行和第 n n n 行的 p p p 值全部为 0 0 0)。

现在某组织打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选 择任意多的人从任意的门进入,但必须到达第 n n n 行的每个房间。一个士兵受到的伤害值为他到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士兵的行进路线可以使得整个部队的伤害值最小。

【输入格式】

第一行有两个整数 n , m n,m n,m,表示迷阵的大小。

接下来 n n n 行,每行 m m m 个数,第 i i i 行第 j j j 列的数表示 p i , j p_{i,j} pi,j

【输出格式】

输出一个数,表示最小伤害代价。

【示例一】

输入

4 2
0 0 
3 5 
2 4 
0 0

输出

3

【说明/提示】

  • 50 % 50\% 50% 的数据, n , m ≤ 100 n,m \leq 100 n,m100
  • 100 % 100\% 100% 的数据, n , m ≤ 1000 n,m \leq 1000 n,m1000 p i , j ≤ 1000 p_{i,j} \leq 1000 pi,j1000

(1) 解题思路

其实这道题问的就是,在所有从第一行到最后一行的路径中,都有一个经过的数字的最大值,求这些最大值中最小的那个是多少。如果我们把所有的路径都枚举一遍,显然是会超时的。但是仔细一看这道题说的是最大值最小的问题,我们自然就要想到二分

对于我们枚举一个数值 x,检查在伤害不超过 x 的情况下能够打开所有机关(能否从最上面走到最下面)。如果不能,那么这个 x 一定枚举大了,反之则小了。而这里的枚举 x 显然是用二分去枚举,检查能否打开所有机关则可用多源 BFS。


(2) 代码实现

#include<iostream>
#include<queue>
#include<cstring>using namespace std;typedef pair<int, int> PII;
const int N = 1010;
int mat[N][N];
bool vis[N][N];
int n, m;int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};// 在伤害不超过 x 的情况下打开全部机关
bool check(int x)
{memset(vis, false, sizeof(vis));queue<PII> q;// 把第一行所有位置都加入到队列中for(int j = 1; j <= m; j++){q.push({1, j});vis[1][j] = true;}// 多源 BFS// 看 BFS 能不能走到最后一行,这是检验能否到达的标准while(!q.empty()){int r = q.front().first;int c = q.front().second;q.pop();for(int i = 0; i < 4; i++){int rr = r + dx[i];int cc = c + dy[i];if(rr == n) return true;  // 如果能走到最后一行,则返回 true// 只把合法并且值小于 x 的位置加入到队列中if(rr > 0 && rr < n && cc > 0 && cc <= m && !vis[rr][cc] && mat[rr][cc] <= x){q.push({rr, cc});vis[rr][cc] = true;}}}return false;
}int main()
{cin >> n >> m;for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)cin >> mat[i][j];int left = 0, right = 1000;while(left < right){int mid = (left + right) / 2;if(check(mid)) right = mid;else left = mid + 1;}cout << left << endl;return 0;
}
http://www.dtcms.com/a/486078.html

相关文章:

  • *@UI 视角下主程序与子程序的菜单页面架构及关联设计
  • Virtio 半虚拟化技术解析
  • 网站设计怎么好看律师做网络推广哪个网站好
  • 用commons vfs 框架 替换具体的sftp 实现
  • 网站模板怎么设计软件wordpress多重筛选页面
  • 通往Docker之路:从单机到容器编排的架构演进全景
  • 分布式链路追踪:微服务可观测性的核心支柱
  • PostgreSQL 函数ARRAY_AGG详解
  • 【OpenHarmony】MSDP设备状态感知模块架构
  • RAG 多模态 API 处理系统设计解析:企业级大模型集成架构实战
  • 通过一个typescript的小游戏,使用单元测试实战(二)
  • 多物理域协同 + 三维 CAD 联动!ADS 2025 解锁射频前端、天线设计新体验
  • 前端微服务架构解析:qiankun 运行原理详解
  • linux ssh config详解
  • 内网攻防实战图谱:从红队视角构建安全对抗体系
  • 鲲鹏ARM服务器配置YUM源
  • 网站分类标准沈阳网站制作招聘网
  • 建设一个网站需要几个角色建筑工程网课心得体会
  • 基于Robosuite和Robomimic采集mujoco平台的机械臂数据微调预训练PI0模型,实现快速训练机械臂任务
  • 深度学习目标检测项目
  • SQL 窗口函数
  • 盟接之桥浅谈目标落地的底层逻辑:实践、分解与认知跃迁
  • 【Qt】4.项目文件解析
  • Redis-布隆过滤器BloomFilter
  • 网站建设找至尚网络深圳制作企业网站
  • 网页是网站吗苏州刚刚发生的大事
  • WPF中RelayCommand的实现与使用详解
  • 百度天气:空气质量WebGIS可视化的创新实践 —— 以湖南省为例
  • Flutter---GridView+自定义控件
  • OJ竞赛平台----C端题目列表