SPFA的两个优化
评测题:洛谷【模板】单源最短路径
不加任何优化:
- queue<int>q;
- void spfa(ll s)
- {
- for(ll i=;i<=n;i++) d[i]=(ll)();
- d[s]=;q.push(s);v[s]=;
- while(!q.empty())
- {
- ll ff=q.front();q.pop();v[ff]=;
- for(ll i=h[ff];i;i=e[i].ne)
- {
- ll rr=e[i].v;
- if(d[rr]>d[ff]+e[i].c)
- {
- d[rr]=d[ff]+e[i].c;
- if(!v[rr]) q.push(rr),v[rr]=;
- }
- }
- }
- }
==================================================
优化1(SLF:Small Label First):
使用双端队列(详见代码注释)
证明:显然定理
- deque<ll>q;
- void spfa(ll s)
- {
- for(ll i=;i<=n;i++) d[i]=(ll)(),v[i]=;
- d[s]=;q.push_back(s);v[s]=;//双端队列
- while(!q.empty())
- {
- ll ff=q.front();q.pop_front();v[ff]=;
- for(ll i=h[ff];i;i=e[i].ne)
- {
- ll rr=e[i].v;
- if(d[rr]>d[ff]+e[i].c)
- {
- d[rr]=d[ff]+e[i].c;
- if(!v[rr])
- {
- if(q.empty() || d[rr]>=d[q.front()]) q.push_back(rr);
- else q.push_front(rr);
- //如果当前点的dis<队列首的dis,就把当前点放在队列首
- //让它优先去更新其他点,减少入队次数
- //注意,特殊情况,如果队列为空的话,要放在队列为,不然会RE
- v[rr]=;
- }
- }
- }
- }
- }
==================================================================================
优化2(LLL:Large Label Last):
使用双端队列,sum为队列中所以元素的dis和,o为队列中元素个数
即x=sum/o;
对于当前点i,如果dis[i]>=x 则将点i插入到队列尾,否则放到队列首。
证明:不会。
- deque<int>q;
- void spfa(ll s)
- {
- for(ll i=;i<=n;i++) d[i]=(ll)();
- d[s]=;q.push_back(s);v[s]=;
- sum+=d[s];o++;
- while(!q.empty())
- {
- ll ff=q.front();q.pop_front();v[ff]=;
- sum-=d[ff];o--;
- for(ll i=h[ff];i;i=e[i].ne)
- {
- ll rr=e[i].v;
- if(d[rr]>d[ff]+e[i].c)
- {
- d[rr]=d[ff]+e[i].c;
- if(!v[rr])
- {
- v[rr]=;
- if(q.empty() || o*d[rr]>=sum) q.push_back(rr);
- else q.push_front(rr);
- //注意,特殊情况,如果队列为空的话,要放在队列为,不然会RE
- }
- }
- }
- }
- }
=====================================================
两个优化一起上:
- bool v[];
- deque<int>q;
- void spfa(ll s)
- {
- for(ll i=;i<=n;i++) d[i]=(ll)();
- d[s]=;q.push_back(s);v[s]=;
- sum+=d[s];o++;
- while(!q.empty())
- {
- ll ff=q.front();q.pop_front();v[ff]=;
- sum-=d[ff];o--;
- for(ll i=h[ff];i;i=e[i].ne)
- {
- ll rr=e[i].v;
- if(d[rr]>d[ff]+e[i].c)
- {
- d[rr]=d[ff]+e[i].c;
- if(!v[rr])
- {
- v[rr]=;
- if(q.empty() || d[rr]>=d[q.front()] || o*d[rr]>=sum)
- q.push_back(rr);
- else q.push_front(rr);
- }
- }
- }
- }
- }
至此,完。
腐草无光,化为萤而跃彩于夏月。
SPFA的两个优化的更多相关文章
- SPFA 的两个优化
From NOCOW SPFA算法有两个优化算法 SLF 和 LLL: SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)<dist(i),则将 ...
- SPFA的两个优化:SLF与LLL
先举出个例题:洛谷P3371 [模板]单源最短路径 一眼扫去:最短路径. spfa不接受反驳... 附上代码: #include<iostream> #include<algorit ...
- SPFA的两种优化
SPFA是可以优化的,这个大家都是晓得的吧. 下面介绍两种SPFA的神奇优化(我只代码实现了的一种) SLF:Small Label First策略,设要加入的节点是j,队首元素为i,若dist(j) ...
- SPFA的两个(卡时)优化
SPFA算法有两个优化算法 SLF 和 LLL: SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)<dist(i),则将j插入队首,否则插入队 ...
- poj 3259 Wormholes : spfa 双端队列优化 判负环 O(k*E)
/** problem: http://poj.org/problem?id=3259 spfa判负环: 当有个点被松弛了n次,则这个点必定为负环中的一个点(n为点的个数) spfa双端队列优化: 维 ...
- WebGPU学习(十一):学习两个优化:“reuse render command buffer”和“dynamic uniform buffer offset”
大家好,本文介绍了"reuse render command buffer"和"dynamic uniform buffer offset"这两个优化,以及Ch ...
- 2013成都邀请赛J称号||HDU4725 The Shortest Path in Nya Graph(spfa+slf最短的优化)
职务地址:HDU 4725 这题卡了好长时间了,建图倒是会建,可是不会最短路的算法优化,本以为都须要堆去优化的,打算学了堆之后再来优化.可是昨晚CF的一道题..(那题也是不优化过不了..)然后我就知道 ...
- SPFA算法的SLF优化 ——loj#10081. 「一本通 3.2 练习 7」道路和航线
今天做到一道最短路的题,原题https://loj.ac/problem/10081 题目大意为给一张有n个顶点的图,点与点之间有m1条道路,m2条航线,道路是双向的,且权值非负,而航线是单向的,权值 ...
- ACM/ICPC 之 SPFA练习两道(ZOJ3088-ZOJ3103)
两道题都需要进行双向SPFA,比范例复杂,代码也较长,其中第二题应该可以用DFS或者BFS做,如果用DFS可能需要的剪枝较多. ZOJ3088-Easter Holydays //利用SPFA找出下降 ...
随机推荐
- 测开之路一百零七:bootstrap排版
引入bootstrap和jquery 标题 对齐 正文强调 引言 <!DOCTYPE html><html lang="en"><head> & ...
- 应用安全 - SuiteCRM - 漏洞汇总
CVE-2019-12598.CVE-2019-12601 SuiteCRM SQL注入与远程代码执行漏洞 SalesAgility SuiteCRM .x版本..x版本和7..5之前的7..x版本中 ...
- Vue 基础 day02
Vue Devtools 安装 https://chrome.google.com/webstore/search/vue%20devtools?hl=zh-CN 需要翻墙 过滤器 概念: Vue.j ...
- [Python3 填坑] 012 字典的遍历在 Python2 与 Python3 中区别
目录 1. print( 坑的信息 ) 2. 开始填坑 2.1 Python2 中字典的遍历 2.2 Python3 中字典的遍历 2.3 结论 1. print( 坑的信息 ) 挖坑时间:2019/ ...
- MySQL学习笔记(上)
在进行SQL注入原理的剖析的时候,对MySQL数据库掌握薄弱,参照菜鸟教程的MySQL教程速刷一遍MySQL 关于MySQL MySQL是最流行的关系型数据库管理系统,在WEB方面MySQL是最好的R ...
- qt 保存文件为utf8
转载:https://www.cnblogs.com/cppskill/p/7999800.html bool TdrawSvg::Save2File(char* _pcFullFileName) { ...
- [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)
[BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...
- osi七层协议 Open System Interconnection
一, 操作系统基础 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必 ...
- python 模块调用的几种方式
在python里面又很多模块,或者引用第三方模块,python 模块调用的几种方式,下面详细解说 1,import 模块名 2,from 模块 import 模块里面的小功能 3,from 模块 ...
- RMAN备份与恢复 —— 参数文件还原
在RMAN用语中,“还原”与“恢复”具有不同的含义,还原(restore)是指访问先前生成的备份集,从中得到一个或多个对象,然后再磁盘上的某个位置还原这些对象.还原与恢复时分离的.恢复(re ...