纠正我对 01-BFS 问题的错误认识。

我一直以为对于 01-BFS,每次点 $u$ 出队时,对于 $u$ 的邻接边表中的边,只要先松弛边权为 0 的边再松弛边权为 1 的边就能保证每个点只入队一次。最近我发现我错了,例子:



按照上述做法,入队序列是 1, 2, 3, 4, 5, 4, 5。4、5 这两个点入队两次。

一个自然的想法是用一个布尔数组来标记每个点当前是否在队列中以避免重复入队,然而这是行不通的。



出入队序列是

+1, -1, +2, +3, -2, +4, +5, -3, -4, -5, +4, -4

可见 4 号点入队了两次。

01-BFS 的正确做法是用双端队列代替普通队列。每次点 $u$ 出队时,对于 $u$ 的邻接边表中的能够被松弛的有向边 $(u, v)$,若 $(u,v)$ 权值是 0,则将 $v$ 放到队首,否则将 $v$ 放到队尾。当 $(u, v)$ 权值是 0 时,将 $v$ 放到队首相当于把 $v$ 提到了 $u$ 所在的那一层,或者说把 $u$ 和 $v$ 缩成一个点。

代码:

const int max_n = 5000;
vector<int> dis(max_n, INT_MAX);
vector<pair<int,int>> g(max_n); void bfs(int s) {
dis[s] = 0;
deque<int> que;
que.push(s);
while (!que.empty()) {
auto u = que.front();
que.pop_front();
for (auto& e, g[u]) {
if (dis[u] + e.second < dis[e.first]) {
dis[e.first] = dis[u] + e.second;
if (e.second == 0) {
que.push_front(e.first);
} else {
que.push_back(e.first);
}
}
}
}
}

【B2B】01-BFS的更多相关文章

  1. 【LeetCode】01 Matrix 解题报告

    [LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...

  2. 【u115】&&【t031】 01迷宫

    01迷宫(maze01) Time Limit: 1 second Memory Limit: 128 MB [问题描述] 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相 ...

  3. 【hdu3080】01背包(容量10^7)

    [题意]n个物品,有wi和vi,组成若干个联通块,只能选取一个联通块,问得到m的价值时最小要多少空间(v).n<=50,v<=10^7 [题解] 先用并查集找出各个联通块. 这题主要就是v ...

  4. 【C】 01 - 再学C语言

    “C语言还用再学吗?嵌入式工程师可是每天都在用它,大家早就烂熟于心,脱离语言这个层面了”.这样说不无道理,这门古老的语言以其简单的语法.自由的形式的而著称.使用C完成工作并不会造成太大困扰,所以很少有 ...

  5. 【BZOJ3003】LED BFS+状压DP

    [BZOJ3003]LED Description LED屏是由一个庞大的点阵小灯泡组成的,一开始每个小灯泡都不发光.每一行一共有N个小灯泡,依次标号为1~n.现在给定K个点,要求这K个点发光,其余点 ...

  6. 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会

    01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...

  7. 【整理】01. Fiddler 杂记

    抓手机包步骤: Tools -- Fiddler Options -- Connections (默认)Fiddler listens on port:8888 (勾选)Allow remote co ...

  8. 【OracleDB】 01 概述和基本操作

    实例概念: Oracle有一个特殊的概念 Oracle数据库 = 数据库 + Oracle文件系统 + Oracle实例 实例处理Oracle的请求,调用文件系统 然后返回结果响应给客户端 单实例和多 ...

  9. 【B2B】2015 年B2B的春天

    摘要 看看关于B2B的现状,以及行业发展近况. 现状 http://www.cyzone.cn/a/20160115/288471.html 行业发展 蓬勃发展的行业: 方兴未艾的行业: 未来的行业:

  10. 【NOIP2013】 华容道 bfs预处理+bfs

    这一题我们考虑一个最裸的算法: 我们设$dp[i][j][k][l]$表示当前棋子在$(i,j)$且空格在$(k,l)$时的最小步数 然后显然随便转移一下就好了,时间复杂度为$O(q(nm)^2)$. ...

随机推荐

  1. hdu 5810 Balls and Boxes 二项分布

    Balls and Boxes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  2. vue子路由设置、全局组件、局部组件的原生写法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. canvas小实验

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. linux IP 网关配置

    1. 关闭selinux 与防火墙 在虚拟机装好之后之后,先关闭selinux与防火墙 关闭selinx,重启生效 vim /etc/selinux/config 修改 SELINUX=disable ...

  5. zookeeper系列(八)zookeeper客户端的底层详解

    作者:leesf    掌控之中,才会成功:掌控之外,注定失败.出处:http://www.cnblogs.com/leesf456/p/6098255.html 尊重原创,共同学习进步:  一.前言 ...

  6. *CodeIgniter框架集成支付宝即时到账SDK

    客户的网站需要支付功能,我们选择了业界用的最多的支付宝即时到账支付.申请了两次将近两周的时间终于下来了,于是我开始着手测试SDK整合支付流程. SDK中的代码并不复杂,就是构造请求发送,接收并验证签名 ...

  7. Oracle 表空间扩容

    1 系统表空间扩容 注:表空间监测或扩容方式很多,这里只提供一种方便使用的方法 1)查询SQL 注:需要输入百分比,如:90,就可查出使用率超过90%的表空间, with t as (select b ...

  8. win7配置flutter报错 运行flutter doctor报错及解决方法

    先按照官方文档进行配置 win10下按照flutter官方文档进行部署flutter 基本没有任何问题 win7情况下 按照官方文档操作后 前面也都可以正常进行 直到 win7下运行flutter d ...

  9. leetcode315 计算右侧小于当前元素的个数

    1. 采用归并排序计算逆序数组对的方法来计算右侧更小的元素 time O(nlogn): 计算逆序对可以采用两种思路: a. 在左有序数组元素出列时计算右侧比该元素小的数字的数目为 cnt=r-mid ...

  10. LC 470. Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...