多源 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)的坐标加入队列,并设置其距离为0。 -
其他节点的距离初始化为
-1,表示未访问。
-
-
BFS 扩展阶段
-
从队列中取出节点,检查四个方向的相邻节点。
-
若相邻节点在网格内且未被访问,更新其距离为当前节点距离
+1,并将其加入队列。
-
五、应用场景
-
计算多个起点到所有节点的最短距离(如疫情传播模拟、火源蔓延模型)。
-
地图中多个商店到用户的最短路径计算。
六、注意事项
-
边权必须为 1:若边权不同,需使用 Dijkstra 或 Floyd-Warshall 算法。
-
空间优化:可直接在原数组上修改距离,避免额外空间开销。
-
性能优势:相比暴力法(每个源点单独 BFS),时间复杂度从 O(kN) 优化到 O(N),其中 k 是源点数量。
通过多源 BFS,我们能够以高效的方式解决多个起点同时扩散的最短路径问题,是图论中一种重要的优化技巧。
相关文章:
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
多源 BFS 是一种解决 边权为 1 的多源最短路问题 的高效算法。其核心思想是将所有源点视为一个“超级源点”,通过一次 BFS 遍历即可计算所有节点到最近源点的最短距离。以下从原理、实现和代码示例三个方面深入讲解: 目录 一、原理分析 1. 单源 BFS vs…...
使用IDEA提交SpringBoot项目到Gitee上
登录Gitee并新建仓库 创建本地仓库 提交本地代码到本地仓库 提交本地代码到远程仓库...
我们来学人工智能 -- DeepSeek客户端
DeepSeek客户端 题记使用后记系列文章 题记 我选择了 Cherry Studio是国内产品由CherryHQ团队开源是一个平台在这里,有豆包、kimi、通义千问的入口当然,最主要是作为大模型的UI正如标题,这里,作为DeepSeep的客户端 使用 下载本…...
【Linux】匿名管道的应用场景-----管道进程池
目录 一、池化技术 二、简易进程池的实现: Makefile task.h task.cpp Initchannel函数: 创建任务: 控制子进程: 子进程执行任务: 清理收尾: 三、全部代码: 前言: 对于管…...
JavaScript函数-函数的使用
在JavaScript编程中,函数不仅是组织代码的基本单元,也是实现复杂逻辑、提高代码复用性和可维护性的关键工具。无论你是刚开始学习JavaScript的新手,还是希望深入理解函数使用的开发者,本文都将为你提供全面的指导。 函数的基础知…...
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 代码+开发文档+视频教程
水果生鲜农产品推荐系统 协同过滤余弦函数推荐水果生鲜农产品 Springboot Vue Element-UI前后端分离 【亮点功能】 1.SpringbootVueElement-UIMysql前后端分离 2.Echarts图表统计数据, 直观展示数据情况 3.发表评论后,用户可以回复评论, 回复的评论可以被再次回复, …...
Android输入事件传递流程系统源码级解析
1. 硬件层到Linux内核 设备节点:触摸事件由内核驱动捕获,写入/dev/input/eventX。关键结构体:input_event(包含时间戳、类型、代码、值)。 2. Native层处理(system_server进程) 2.1 EventHub …...
自制操作系统学习第七天
今天要做什么? 实现HLT,不让计算机处于HALT(HLT).用C语言实现内存写入(错误,需要分析) 一:使用HLT,让计算机处于睡眠状态 写了下面这个程序,naskfunc.nas 函数名叫io_h…...
【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】
最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…...
Coze插件之基于IDE创建插件
上篇文章中,我们基于已有服务创建了一些插件和工具。方便我们开发更多工作流和智能体应用。 本篇文章要介绍的是基于IDE进行创建,为什么有了基于服务创建后还有基于IDE进行创建呢?基于IDE进行创建有哪些优势? 对于一些简单操作&…...
deepseek的模型经过训练 ai写出了linux 64位加壳软件
1. 加壳程序的设计目标 目标:保护64位Linux下的可执行文件,使其难以被反编译或调试。核心功能: 在运行时加载原始可执行文件并解密。隐藏壳代码和原程序的真正入口点。提供一定的反调试机制。 2. 思路 加壳流程: 加载器…...
解锁音频新境界:LALAL.AI 与 Audo Studio 深度解析
在音频处理的世界里,噪音常常是困扰我们的一大难题。无论是专业的音频工作者,还是普通的音频爱好者,都渴望拥有一款强大的工具来解决这个问题。今天,就为大家介绍两款来自 AI 工具导航(AIDH.NET)的 AI 语音…...
Kubernetes 使用 Kube-Prometheus 构建指标监控 +飞书告警
1 介绍 Prometheus Operator 为 Kubernetes 提供了对 Prometheus 机器相关监控组件的本地部署和管理方案,该项目的目的是为了简化和自动化基于 Prometheus 的监控栈配置,主要包括以下几个功能: Kubernetes 自定义资源:使用 Kube…...
20250221 NLP
1.向量和嵌入 https://zhuanlan.zhihu.com/p/634237861 encoder的输入就是向量,提前嵌入为向量 二.多模态文本嵌入向量过程 1.文本预处理 文本tokenizer之前需要预处理吗? 是的,文本tokenizer之前通常需要对文本进行预处理。预处理步骤可…...
【C++】const关键字的作用及常见应用场景
一、核心作用 用于定义“常量”,限制程序对变量的修改,提升代码安全性和可读性。其核心作用包括: 避免误修改:明确标识不可变数据。编译器优化:常量可被放入符号表,减少内存访问,优化执行效率…...
04控制流
一、二路分支 逻辑:程序中某段代码需要在满足某个条件时才能运行形式: if 语句:表达一种 如果-则 的条件执行关系if-else 语句:表达一种 如果-否则 的互斥分支关系 流程图: 注意: if 语句可以单独使用&…...
【Leetcode 每日一题】2506. 统计相似字符串对的数目
问题背景 给你一个下标从 0 0 0 开始的字符串数组 w o r d s words words。 如果两个字符串由相同的字符组成,则认为这两个字符串 相似 。 例如,“abca” 和 “cba” 相似,因为它们都由字符 ‘a’、‘b’、‘c’ 组成。然而,“…...
【Shell编程 / 9】脚本实战项目:从基础到进阶的自动化管理方案
文章目录 Shell脚本实战项目自动化部署脚本系统监控脚本文件备份脚本定时任务管理脚本文件传输自动化脚本自动化日志清理脚本用户管理脚本 Shell脚本实战项目 在掌握了 Shell 脚本的基本语法和高级技巧后,实践是进一步提升脚本编写能力的关键。通过参与一些实际的项…...
在PyTorch中使用插值法来优化卷积神经网络(CNN)所需硬件资源
插值法其实就是在已知数据点之间估计未知点的值。通过已知的离散数据点,构造一个连续的曲线函数,预测数据点之间的空缺值是什么并且自动填补上去。 适用场景: 在卷积神经网络(CNN)中的应用场景中,经常遇到计算资源有限,比如显存不够或者处理速度慢,需要用插值来降低计…...
黄金市场现状与驱动因素分析
一、当前市场现状:挤兑、运力与供应链危机 全球金库告急与运输瓶颈 伦敦商业银行金库的黄金存量告急,纽约和伦敦市场出现“史诗级挤兑”。提取英格兰银行金库的黄金需等待4-8周,远高于常规的几天时间[citation:用户描述]。专业运输车辆超负荷…...
Python静态分析工具Pylint、Flake8与Mypy实战指南
1. Python静态分析工具深度解析在Python开发中,静态分析工具就像一位经验丰富的代码审查员,能在不实际运行程序的情况下发现潜在问题。这类工具通过解析源代码来检查语法错误、编码风格违规和潜在逻辑缺陷。对于机器学习项目而言,这些工具尤为…...
浏览器扩展开发插件与内容脚本
浏览器扩展开发插件与内容脚本:解锁网页的无限可能 在当今数字化时代,浏览器已成为我们日常工作和娱乐的核心工具。而浏览器扩展开发插件与内容脚本,则为用户和开发者提供了定制化浏览体验的强大能力。无论是广告拦截、自动化操作࿰…...
Cesium地图服务商大比拼:在Vue3项目中如何选择并接入ArcGIS、Bing、OSM和国内天地图?
Vue3Cesium地图服务选型实战:从ArcGIS到天地图的深度对比与集成指南 在智慧城市、物流追踪和地理信息可视化领域,地图底图的选择直接影响着用户体验和系统性能。作为前端工程师,我们常常陷入这样的困境:ArcGIS的影像精度令人心动但…...
为什么你的Docker AI服务永远跑不满GPU?——NVIDIA DCNM+Dockerd定制调度器部署手册(限内部团队解密版)
第一章:为什么你的Docker AI服务永远跑不满GPU?——NVIDIA DCNMDockerd定制调度器部署手册(限内部团队解密版)GPU资源利用率长期低于40%?不是显存瓶颈,而是Docker原生调度器根本“看不见”GPU拓扑与NUMA亲和…...
ElasticSearch 核心:分片策略全解析 + 分片/副本数精准配置实战
ElasticSearch 核心:分片策略全解析 分片/副本数精准配置实战一、前言二、基础概念:ES 分片与副本2.1 核心定义2.2 分片工作流程图三、ElasticSearch 分片策略全解析3.1 策略1:默认哈希路由策略(最常用)3.1.1 原理3.1…...
STM32/GD32烧录失败别慌:手把手教你用BOOT0引脚和Keil的‘under Reset’模式救砖
STM32/GD32烧录失败自救指南:从硬件短接到调试模式全解析 第一次遇到芯片无法烧录的情况时,那种手足无措的感觉我至今记忆犹新。开发板静静地躺在桌面上,Keil里不断弹出的错误提示仿佛在嘲笑我的无能。但别担心,这几乎是每个嵌入式…...
终极Boss-Key老板键:如何一键隐藏窗口保护你的数字隐私?
终极Boss-Key老板键:如何一键隐藏窗口保护你的数字隐私? 【免费下载链接】Boss-Key 老板来了?快用Boss-Key老板键一键隐藏静音当前窗口!上班摸鱼必备神器 项目地址: https://gitcode.com/gh_mirrors/bo/Boss-Key 在现代数字…...
WindowResizer终极指南:如何强制调整任意Windows窗口大小
WindowResizer终极指南:如何强制调整任意Windows窗口大小 【免费下载链接】WindowResizer 一个可以强制调整应用程序窗口大小的工具 项目地址: https://gitcode.com/gh_mirrors/wi/WindowResizer 你是否曾遇到过那些"顽固"的Windows应用程序窗口&a…...
3个步骤从零开始获取全国高铁数据:探索Parse12306的自动化数据采集之旅
3个步骤从零开始获取全国高铁数据:探索Parse12306的自动化数据采集之旅 【免费下载链接】Parse12306 分析12306 获取全国列车数据 项目地址: https://gitcode.com/gh_mirrors/pa/Parse12306 你是否曾经好奇,那些铁路查询App是如何获取全国高铁时刻…...
Mos:3分钟彻底解决Mac鼠标滚动卡顿的终极平滑滚动方案
Mos:3分钟彻底解决Mac鼠标滚动卡顿的终极平滑滚动方案 【免费下载链接】Mos 一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具, 让你的滚轮爽如触控板 | A lightweight tool used to smooth scrolling and set scroll direction independently f…...
