多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题

        多源 BFS 是一种解决 边权为 1 的多源最短路问题 的高效算法。其核心思想是将所有源点视为一个“超级源点”,通过一次 BFS 遍历即可计算所有节点到最近源点的最短距离。以下从原理、实现和代码示例三个方面深入讲解:


目录

一、原理分析

1. 单源 BFS vs 多源 BFS

2. 正确性证明

3. 时间复杂度

二、C++ 实现步骤

1. 初始化

2. BFS 扩展

三、代码示例

四、代码解释

初始化阶段

BFS 扩展阶段

五、应用场景

六、注意事项


一、原理分析

1. 单源 BFS vs 多源 BFS

  • 单源 BFS:从单一源点出发,逐层扩展,记录每个节点到该源点的最短距离。

  • 多源 BFS:将多个源点 同时加入队列,作为 BFS 的初始层。每个节点被首次访问时,记录的是到最近源点的最短距离。

2. 正确性证明

  • BFS 的逐层扩展特性保证:当某个节点被首次访问时,其路径长度即为最短距离。

  • 所有源点同时作为初始层,相当于它们处于“第 0 层”,后续扩展的层数即为到最近源点的距离。

3. 时间复杂度

  • 与单源 BFS 相同,时间复杂度为 O(N)(假设共 N 个节点),每个节点和边仅被处理一次。


二、C++ 实现步骤

以二维网格为例,假设 grid 表示网格,其中 1 为源点,0 为可通行节点。目标是计算每个节点到最近源点的距离。

1. 初始化

  • 队列:将所有源点坐标加入队列。

  • 距离数组:源点距离初始化为 0,其他节点初始化为 -1(表示未访问)。

2. BFS 扩展

  • 从队列中取出节点,检查其四个方向(上、下、左、右)。

  • 若相邻节点未被访问过,更新其距离并加入队列。


三、代码示例

#include <vector>
#include <queue>
using namespace std;vector<vector<int>> multiSourceBFS(vector<vector<int>>& grid) {int rows = grid.size();int cols = grid[0].size();queue<pair<int, int>> q;vector<vector<int>> dist(rows, vector<int>(cols, -1));// 初始化:将所有源点加入队列,并设置距离为 0for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (grid[i][j] == 1) {q.push({i, j});dist[i][j] = 0;}}}// 四个移动方向:上、下、左、右vector<pair<int, int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};while (!q.empty()) {auto [x, y] = q.front();q.pop();for (auto [dx, dy] : dirs) {int nx = x + dx;int ny = y + dy;// 检查边界和是否已访问if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && dist[nx][ny] == -1) {dist[nx][ny] = dist[x][y] + 1;q.push({nx, ny});}}}return dist;
}

四、代码解释

  1. 初始化阶段

    • 遍历网格,将所有源点(值为 1)的坐标加入队列,并设置其距离为 0

    • 其他节点的距离初始化为 -1,表示未访问。

  2. BFS 扩展阶段

    • 从队列中取出节点,检查四个方向的相邻节点。

    • 若相邻节点在网格内且未被访问,更新其距离为当前节点距离 +1,并将其加入队列。


五、应用场景

  • 计算多个起点到所有节点的最短距离(如疫情传播模拟、火源蔓延模型)。

  • 地图中多个商店到用户的最短路径计算。


六、注意事项

  1. 边权必须为 1:若边权不同,需使用 Dijkstra 或 Floyd-Warshall 算法。

  2. 空间优化:可直接在原数组上修改距离,避免额外空间开销。

  3. 性能优势:相比暴力法(每个源点单独 BFS),时间复杂度从 O(kN) 优化到 O(N),其中 k 是源点数量。

        通过多源 BFS,我们能够以高效的方式解决多个起点同时扩散的最短路径问题,是图论中一种重要的优化技巧。

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

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

相关文章

【蓝桥杯集训·每日一题2025】 AcWing 6123. 哞叫时间 python

6123. 哞叫时间 Week 1 2月18日 农夫约翰正在试图向埃尔茜描述他最喜欢的 USACO 竞赛&#xff0c;但她很难理解为什么他这么喜欢它。 他说「竞赛中我最喜欢的部分是贝茜说 『现在是哞哞时间』并在整个竞赛中一直哞哞叫」。 埃尔茜仍然不理解&#xff0c;所以农夫约翰将竞赛以…

C++,设计模式,【工厂方法模式】

文章目录 如何用汽车生产线理解工厂方法模式?一、传统生产方式的困境二、工厂方法模式解决方案三、模式应用场景四、模式优势分析五、现实应用启示✅C++,设计模式,【目录篇】 如何用汽车生产线理解工厂方法模式? 某个早晨,某车企CEO看着会议室里堆积如面的新车订单皱起眉…

贪心算法

int a[1000], b5, c8; swap(b, c); // 交换操作 memset(a, 0, sizeof(a)); // 初始化为0或-1 引导问题 为一个小老鼠准备了M磅的猫粮&#xff0c;准备去和看守仓库的猫做交易&#xff0c;因为仓库里有小老鼠喜欢吃的五香豆&#xff0c;第i个房间有J[i] 磅的五香豆&#xf…

机器学习·数据处理

前言 对于大规模数据&#xff0c;我们经常会使用python内置函数或者编写脚本进行批量化处理&#xff0c;从而提高后续使用算法的效率。 1. 正则表达式 定义&#xff1a;用于检索、替换符合某个模式的文本&#xff0c;是文本预处理常用技术。基本语法 符号描述.匹配除换行符 …

大厂出品!三个新的 DeepSeek 平替网站

前几天给大家分享了几个 DeepSeek 免费平替网站&#xff0c;今天又来更新啦。 新增了以下三个平台&#xff1a;火山引擎、知乎直达、百度搜索。 经过实际测试&#xff0c;这几个平台的服务响应速度快&#xff0c;稳定性表现优异&#xff0c;基本不会出现宕机或服务器繁忙的情…

[创业之路-321]:创新开拓思维和经营管理思维的比较

目录 一、概述 1.1、定义与内涵 1、创新开拓思维&#xff1a; 2、经营管理思维&#xff1a; 1.2、特点与优势 1、创新开拓思维的特点与优势&#xff1a; 2、经营管理思维的特点与优势&#xff1a; 3、应用场景与限制 4、总结 二、创新开拓思维与经营管理思维&#xf…

《深度学习实战》第1集:深度学习基础回顾与框架选择

本专栏系列博文旨在帮助读者从深度学习的基础知识逐步进阶到前沿技术&#xff0c;涵盖理论、实战和行业应用。每集聚焦一个核心知识点&#xff0c;并结合实际项目进行实践&#xff0c;避免空谈理论&#xff0c;简洁明快&#xff0c;快速切入代码&#xff0c;所有代码都经过验证…

经典复古嘻哈说唱朋克风格专辑海报标题设计psai英文字体安装包 Punk Of Sad — Ransom Font

Punk Of Sad 将确保您忘记所有简洁的线条和企业润色。这种经典的赎金风格字体是一封写给 DIY 文化的情书&#xff0c;诞生于杂志、演出海报和地下场景的原始能量的剪切和粘贴混乱。每个字母都是不可预测的&#xff0c;都带有叛逆的边缘。 这种字体有三种不同的样式 – Regular…

hot100-滑动窗口

3. 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串的长度。 思路&#xff1a;双指针指向不含重复字符的连续字串的头和尾&#xff0c;用集合存储子串中的元素&#xff0c;有重复时&#xff0c;左指针持续右移&#xff0c;无重复后…

MariaDB 历史版本下载地址 —— 筑梦之路

MariaDB 官方yum源里面只有目前在维护的版本&#xff0c;而有时候对于老项目来说还是需要老版本的rpm包&#xff0c;国内很多镜像站都是同步的官方仓库&#xff0c;因此下载老版本也不好找&#xff0c;这里主要记录下从哪里可以下载到历史版本的MariaDB rpm包。 1. 官方归档网…

Linux-Ansible模块进阶

文章目录 Copy和FetchFile模块 Copy和Fetch copy和fetch模块实践 copy模块需要注意的点&#xff1a;在收集日志之前需要对文件先进行改名或者备份fetch模块需要注意的点&#xff1a;复制的源文件的路径必须是文件不能是目录建议全部使用绝对路径&#xff0c;别使用相对路径确保…

网络空间安全(1)web应用程序的发展历程

前言 Web应用程序的发展历程是一部技术创新与社会变革交织的长卷&#xff0c;从简单的文档共享系统到如今复杂、交互式、数据驱动的平台&#xff0c;经历了多个重要阶段。 一、起源与初期发展&#xff08;1989-1995年&#xff09; Web的诞生&#xff1a; 1989年&#xff0c;欧洲…

国产开源PDF解析工具MinerU

前言 PDF的数据解析是一件较困难的事情&#xff0c;几乎所有商家都把PDF转WORD功能做成付费产品。 PDF是基于PostScript子集渲染的&#xff0c;PostScript是一门图灵完备的语言。而WORD需要的渲染&#xff0c;本质上是PDF能力的子集。大模型领域&#xff0c;我们的目标文件格…

Powershell Install deepseek

前言 deepseekAI助手。它具有聊天机器人功能&#xff0c;可以与用户进行自然语言交互&#xff0c;回答问题、提供建议和帮助解决问题。DeepSeek 的特点包括&#xff1a; 强大的语言理解能力&#xff1a;能够理解和生成自然语言&#xff0c;与用户进行流畅的对话。多领域知识&…

6. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--Ocelot 网关--概念与简单入门

网关是一种位于客户端和后端服务之间的服务&#xff0c;充当所有客户端请求的单一入口。它的主要职责是接收所有的API调用&#xff0c;汇总各类请求&#xff0c;将其路由到适当的后端服务&#xff0c;并将响应返回给客户端。网关不仅仅是一个简单的反向代理&#xff0c;它还能够…

网页制作06-html,css,javascript初认识のhtml如何建立超链接

超链接有外部链接、电子邮件链接、锚点链接、空链接、脚本链接 一、内部链接 与自身网站页面有关的链接被称为内部链接 1、创建内部链接 1&#xff09;语法&#xff1a; <a href"链接地址"> …… </a> 2&#xff09;举例应用&#xff1a; 3&#xf…

MySQL后端返回给前端的时间变了(时区问题)

问题&#xff1a;MySQL里的时间例如为2025-01-10 21:19:30&#xff0c;但是返回到前端就变成了2025-01-10 13:19:30&#xff0c;会出现小时不一样或日期变成隔日的问题 一般来说设计字段时会使用datetime字段类型&#xff0c;这是一种用于时间的字段类型&#xff0c;而这个类型…

【算法与数据结构】单调队列

目录 单调队列 使用单调队列维护滑动窗口 具体过程&#xff1a; 代码实现&#xff1a; 复杂度分析&#xff1a; 使用单调队列优化动态规划 例题 单调队列 单调队列(deque)是一种特殊的队列&#xff0c;队列中的元素始终按严格递增或者递减排列。这样就可以保证队头元素…

AutoGen 技术博客系列 九:从 v0.2 到 v0.4 的迁移指南

本系列博文在掘金同步发布, 更多优质文章&#xff0c;请关注本人掘金账号&#xff1a; 人肉推土机的掘金账号 AutoGen系列一&#xff1a;基础介绍与入门教程 AutoGen系列二&#xff1a;深入自定义智能体 AutoGen系列三&#xff1a;内置智能体的应用与实战 AutoGen系列四&am…

深度学习每周学习总结Y1(Yolov5 调用官方权重进行检测 )

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客Y1中的内容 &#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 ** 注意该训练营出现故意不退押金&#xff0c;恶意揣测偷懒用假的结果冒充真实打卡记录&#xff0c;在提出能够拿到视频录像…