关于SPFA算法的优化方式
关于SPFA算法的优化方式
这篇随笔讲解信息学奥林匹克竞赛中图论部分的求最短路算法SPFA的两种优化方式。学习这两种优化算法需要有SPFA朴素算法的学习经验。在本随笔中SPFA朴素算法的相关知识将不予赘述。
上课!
No.1 SLF优化(Small Label First)
顾名思义,这种优化采用的方式是把较小元素提前。
就像dijkstra算法的堆优化一样。我们在求解最短路算法的时候是采取对图的遍历,每次求最小边的一个过程,为了寻找最小边,我们需要枚举每一条出边,如果我们一上来就找到这个边,那当然是非常爽的。一次找一次爽,一直找一直爽。所以我们采用了这种优化方式。
具体实现方式是把原来的队列变成双端队列,如果新入队的元素比队首元素还要小,就加入到队首,否则排到队尾。
模板如下:
void spfa()
{
memset(dist,0x3f,sizeof(dist));
memset(v,0,sizeof(v));
deque<int> q;
q.push_back(1);
v[1]=1;
dist[1]=0;
while(!q.empty())
{
int x=q.front();
q.pop_front();
v[x]=0;
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(dist[y]>dist[x]+val[i])
{
dist[y]>dist[x]+val[i];
if(v[y]==0)
{
if(dist[y]<=dist[q.pront()])
q.push_front(y);
else
q.push_back(y);
v[y]=1;
}
}
}
}
}
No.2 LLL优化(Large Label Last)
顾名思义,它的策略是把大的元素放到后面。
你会说,这不跟上面的一样么?
不不不,这个优化针对的是出队元素。它的实现过程是:对于每个出队元素,比较它的dist[]和队列中dist的平均值,如果它的dist[]更大,将它弹出放到队尾。以此类推,直至dist[x]小于其平均值。
模板:
void spfa()
{
memset(dis, 0x3f, sizeof(dis));
queue<int> q;
q.push(1);
v[1] = 1;
dist[1] = 0;
cnt = 1;
while(!Q.empty())
{
int x = q.front();
while (dis[x]*cnt > sum)
{
q.pop();
q.push(x);
x = q.front();
}
q.pop();
cnt--;
sum -= dist[x];
v[x] = 0;
for (int i = head[x]; i ; i=nxt[i])
{
int y=to[i];
if (dist[y] > dist[x] + val[i])
{
dist[y] = dist[x] + val[i];
if (v[y]==0)
{
q.push(y);
sum += dist[y];
cnt++;
}
}
}
}
}
重点来了!!
No.3 SLF+LLL同时优化!
听名字就很高级。
是的,的确很高级,不仅高级,而且快。
我就直接上模板了。
void spfa()
{
memset(dist, 0x3f, sizeof(dist));
memset(v,0,sizeof(v));
deque<int> q;
q.push_back(1);
v[1] = 1;
dist[1] = 0;
cnt = 1;
while (!q.empty())
{
int x = q.front();
while (cnt*dist[x] > sum)
{
q.pop_back();
q.push_back(x);
x = q.front();
}
q.pop_front();
cnt--;
sum -= dist[x];
v[x] = 0;
for (int i = head[x]; i ; i=nxt[i])
{
int y=to[i];
if (dist[y] > dist[x] + val[i])
{
dist[y] = dist[x] + val[i];
if (!v[y])
{
if (dist[y] <= dist[q.front()])
q.push_front(y);
else
q.push_back(y);
v[y] = 1;
sum += dist[y];
cnt++;
}
}
}
}
}
下课!祝同学们AK IOI!!
关于SPFA算法的优化方式的更多相关文章
- 《SPFA算法的优化及应用》——姜碧野(学习笔记)
一.核心性质:三角不等式.最短路满足d[v]<=d[u]+w(u,v) 二.SPFA两种实现: 常见的是基于bfs的,这是直接对bellman-ford用队列维护.根据最短路的长度最长为(n-1 ...
- 并不对劲的图论专题(三):SPFA算法的优化
1.bzoj1489-> 这是个新套路. 我们希望找到最小的x,那么可以二分x,然后判断是否存在圈的边权的平均值小于等于x. 设圈的边权依次为w1,w2,w3,…,wk,平均值为p, 则有p= ...
- 蓝书3.3 SPFA算法的优化
T1 最小圈 bzoj 1486 题目大意: 一个环的权值平均值为定义为一个这个环上所有边的权值和除以边数 求最小的环的权值平均值 思路: 二分一个值 把所有边减去这个值 判断是否有负环 #inclu ...
- 队列优化dijsktra(SPFA)的玄学优化
转载:大佬博客 最近想到了许多优化spfa的方法,这里想写个日报与大家探讨下 前置知识:spfa(不带任何优化) 由于使用较多 STLSTL ,本文中所有代码的评测均开启 O_2O2 优化 对一些数 ...
- Dijkstra算法堆优化详解
DIJ算法的堆优化 DIJ算法的时间复杂度是\(O(n^2)\)的,在一些题目中,这个复杂度显然不满足要求.所以我们需要继续探讨DIJ算法的优化方式. 堆优化的原理 堆优化,顾名思义,就是用堆进行优化 ...
- 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)
关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...
- SPFA求最短路——Bellman-Ford算法的优化
SPFA 算法是 Bellman-Ford算法 的队列优化算法的别称,通常用于求含负权边的单源最短路径,以及判负权环.SPFA 最坏情况下复杂度和朴素 Bellman-Ford 相同,为 O(VE), ...
- SPFA算法 - Bellman-ford算法的进一步优化
2017-07-27 22:18:11 writer:pprp SPFA算法实质与Bellman-Ford算法的实质一样,每次都要去更新最短路径的估计值. 优化:只有那些在前一遍松弛中改变了距离点的 ...
- luogu P3371 & P4779 单源最短路径spfa & 最大堆优化Dijkstra算法
P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...
随机推荐
- MYSQL主从复制--传统方式
目录 0.MYSQL主从复制概述 1.主从复制的作用 2.主从复制存在的问题 3.主从复制问题的解决办法 4.主从复制的原理(面试必问) 1.MYSQL主从复制-传统方式 1.环境准备 2.Maste ...
- AD软件笔记
问题1:不同网络的线可以重叠在一起 解决方法1: 在AD中,可以通过 SHIFT+R 快捷键 设置 三种布线模式(忽略 避开 或者 推挤) 解决方法2: 设置规则的Ele ...
- 设计模式-FlyWeight(结构型模式) 针对 需要创建大量对象的情形,被共享的状态作为内部状态,不被共享的状态作为外部状态
以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Flyweight.h #pragma once #include<string> class FlyWeig ...
- expect实现非交互下的ssh连接, expect简单使用整理
1. shell中使用ssh远程连接服务器做一些事情通常需要交互输入些信息, 可使用expect语句解决: 2. expect中设置变量语法: set name xxx set age xxx ...
- Spring Batch与ETL工具比较
在实际应用中,在批处理中用得较多的是场景是数据同步.在做数据集成工作中,常常需要从源位置把数据同步到目标位置,以便于进行后续的逻辑操作.在做这种批处理工具时,在网上查资料,发现用得比较多的是kettl ...
- TensorFlow中实现RNN,彻底弄懂time_step
这篇博客不是一篇讲解原理的博客,这篇博客主要讲解tnesorlfow的RNN代码结构,通过代码来学习RNN,以及讲解time_steps,如果这篇博客没有让你明白time_steps,欢迎博客下面评论 ...
- react组件通信方式汇总
父组件更新组件状态,通过props传递给子组件,子组件得到后进行更新.Timer 是倒计时子组件,集成在了OrderPay父组件里,父组件向子组件传订单数据参数order对象.如下代码: <Ti ...
- 时间time()和$_SERVER['REQUEST_TIME']
文件ab1.php <?phpforeach($i=0;$i<1000;$i++){ echo $time();} 结果: 文件ab2.php <?php foreach($i=0; ...
- CF 704 D. Captain America
CF 704 D. Captain America 题目链接 题目大意:给出\(n\)个点的坐标,你要将每个点染成红色或者蓝色.染一个红色要付出\(r\)的代价,染一个蓝色要付出\(b\)的代价.有\ ...
- 最热门的 10 个 Java 微服务框架
1.Spring Boot Java 构建 Spring 应用程序已经有很长一段时间了,Spring Boot 是 Spring 的一个特定版本,它通过对配置细节的处理,使微服务构建更加简便.创建 S ...