01BFS最短距离的原理和C++实现
最佳答案 问答题库338位专家为你答疑解惑
时间复杂度
O(n),n是边数。
使用前提
边的权只有两种:0,1。
典型场景
n个端点的无向图,编号范围[0,n)。Edges0表示{{n1,n2},...{n3,n4}}表示n1和n2,n3和n4之间有路联接。Edges1表示{{n1,n2},...{n3,n4}}表示n1和n2,n3和n4之间有损坏的路连接。要想让s和d之间至少有一条通道,最小需要维修多少条路。如果无法到达,请返回-1。可能有环,但无自环,重边,可能不联通。
解题思路
可以用类似上章的思路,没损害的路加到pre中,损坏的路加到que中。距离相等的点,谁先谁后无所谓。需要维修的路入队的时候不能计算最短距离,因为不一定是最短边。改在入队计算最短距离,第一层循环记录最短距离。
核心代码
class CBFS1
{
public:CBFS1(vector<vector<int>>& vNeiB0, vector<vector<int>>& vNeiB1, int s){m_vDis.assign(vNeiB0.size(), -1);//m_vDis[s] = 0;queue<int> pre;pre.emplace(s);for (int i = 0; pre.size(); i++){queue<int> dp;while (pre.size()){const int cur = pre.front();pre.pop();if (-1 != m_vDis[cur]){continue;}m_vDis[cur] = i;for (const auto next : vNeiB0[cur]){pre.emplace(next);}for (const auto next : vNeiB1[cur]){dp.emplace(next);}}dp.swap(pre);}}
public:vector<int> m_vDis;
};
测试样例
#define CBFS CBFS1
class CDebugBFS : public CBFS
{
public:
using CBFS::CBFS;
void Assert(const vector<int>& vDis)
{
for (int i = 0; i < vDis.size(); i++)
{
assert(vDis[i] == m_vDis[i]);
}
}
};
struct CDebugParam
{
int n;
vector<vector<int>> edges0;
vector<vector<int>> edges1;
int s;
vector<int> dis;//答案
};
int main()
{
vector<CDebugParam> params = { {1,{},{},0,{0}},{2,{},{},0,{0,-1}},{2,{{0,1}},{},0,{0,0}},{2,{},{{0,1}},0,{0,1}},
{6,{}, { {0,1},{1,2},{1,3},{2,4},{4,5},{3,5}},0,{0,1,2,2,3,3} },
{6,{{3,5}}, { {0,1},{1,2},{1,3},{2,4},{4,5}},0,{0,1,2,2,3,2} }
};
for (const auto& par : params)
{
auto vNeiB0 = EdgeToNeiBo(par.n, par.edges0);
auto vNeiB1 = EdgeToNeiBo(par.n, par.edges1);
CDebugBFS bfs(vNeiB0, vNeiB1,par.s);
bfs.Assert(par.dis);
}
}
类似场景
魔塔经典问题,砸墙需要一个锄头,没墙的地方可以随便移动,如果用尽可能少的锄头到达目的地。许多游戏经过箭塔附件时,会遭到箭塔攻击。如何已最小的损坏通过箭塔。
用双向队列优化
当前状态
操作
新状态
空
处理结束
首尾入队
一种最短距离
一种最短距离
出队
状态不变或变为空
队首入队
一种最短距离或两种最短距离
队尾入队
一种最短距离或两种最短距离
二种最短距离
出队
状态不变或变为一种最短距离
队首入队
两种最短距
队尾入队
两种最短距
class C01BFSDis
{
public:C01BFSDis(vector<vector<int>>& vNeiB0, vector<vector<int>>& vNeiB1, int s){m_vDis.assign(vNeiB0.size(), -1);std::deque<std::pair<int,int>> que;que.emplace_back(s,0);while (que.size()){auto it = que.front();const int cur = it.first;const int dis = it.second;que.pop_front();if (-1 != m_vDis[cur]){continue;}m_vDis[cur] = it.second;for (const auto next : vNeiB0[cur]){if (-1 != m_vDis[next]){continue;} que.emplace_front(next,dis);}for (const auto next : vNeiB1[cur]){if (-1 != m_vDis[next]){continue;}que.emplace_back(next, dis+1);}}}
public:vector<int> m_vDis;
};
测试环境
Win10 VS2022 C++17
下载
doc文档下载(排版好):
https://download.csdn.net/download/he_zhidan/88348653
源码下载:
https://download.csdn.net/download/he_zhidan/88383828
99%的人还看了
相似问题
- 求2个字符串的最短编辑距离 java 实现
- noip模拟赛多校第八场 T3 遥控机器人 (最短路 + 技巧拆点)
- 最短路径:迪杰斯特拉算法
- 【算法】滑动窗口题单——3.不定长滑动窗口(求最短/最小)⭐ 删除最短的子数组使剩余数组有序
- 图的应用2.0-----最短通路问题(Dijkstra和Floyd算法)
- 【MATLAB源码-第58期】基于蛇优化算法(SO)和粒子群优化算法(PSO)的栅格地图路径规划最短路径和适应度曲线对比。
- 华为OD技术面试-最短距离矩阵(动态规划、广度优先)
- 最短路相关笔记
- 图论05-【无权无向】-图的广度优先BFS遍历-路径问题/检测环/二分图/最短路径问题
- 【最短路径算法】一文掌握Dijkstra算法,详解与应用示例+代码
猜你感兴趣
版权申明
本文"01BFS最短距离的原理和C++实现":http://eshow365.cn/6-15391-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: Leetcode 1239. 串联字符串的最大长度
- 下一篇: Go解码S表达式