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找出下降 ...
随机推荐
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_02 递归_3_练习_使用递归计算阶乘
结束条件是乘到 当前数字等于1
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_04 IO字节流_11_字节输入流一次读取多个字节
参数带字节数组的 把字节数组转换为字符串 文件里面有ABCDE 再来读取一次 再来读取一次.读取的结果是ED 再来读取,-1到时输出了.但是还是把ED读取出来了. 原理 第一步创建流对象 第二部创建数 ...
- stack() unstack()函数
总结: 1.stack: 将数据的列索引转换为行索引 2.unstack:将数据的行索引转换为列索引 3.stack和unstack默认操作为最内层,可以用level参数指定操作层. 4.stack ...
- 类Vector
/* * Vector的特有功能 * * Vector出现较早,比集合更早出现 * * 1:添加功能 * public void addElement(Object obj);//用add()替代 * ...
- [转载]OpenSSL中文手册之命令行详解(未完待续)
声明:OpenSSL之命令行详解是根据卢队长发布在https://blog.csdn.net/as3luyuan123/article/details/16105475的系列文章整理修改而成,我自己 ...
- 剑指offer(1):数组
1 写作计划 最近在看<剑指offer>,发现自己有很多的数据结构与算法的基础知识要复习,<好书一起读(131):让写作更好>中提到用写作倒逼阅读,我很是赞同.所以,计划以&l ...
- C++笔记(5)——浮点数的比较
判断是否相等 因为一个浮点数的存储并不总是精确的,例如在经过大量计算之后可能会将3.14保存为3.1400000000001或者3.1439999999999,这时候如果直接用==来比较这两个数的话会 ...
- Java 位运算符和移位运算符
一,运算的位运算符: & ~ | ^ 主要是对二进制的位计算 : & : 两个操作数中位都为1 结果才为1 其他结果为0 forExample: 128 ...
- js json中的时间转换格式
//根据json中的日期格式,转换成yyyy-mm-dd HH:mm:ss function ChangeDateFormat(cellval) { var date = new Date(parse ...
- ceph部署问题解决
注意:1.ceph-deploy实用程序将输出文件到当前目录.执行ceph-deploy时确保你在这个目录下.2.不要使用sudo调用ceph-deploy,要么以root用户身份运行它,因为它不会发 ...