【为什么要优化】

关于SPFA,他死了(懂的都懂)

 

进入正题。。。

一般来说,我们有三种优化方法。

SLF优化:

SLF优化,即 Small Label First  策略,使用 双端队列 进行优化。

一般可以优化15%~20%,在竞赛中比较常用。

设从 u 扩展出了 v ,队列中队首元素为 k ,若 dis[ v ] < dis[ k ] ,则将 v 插入队首,否则插入队尾。

注:队列为空时直接插入队尾。

 deque<int> q;

 inline void spfa(int x)
{
memset(d,0x3f,sizeof(d));
memset(v,,sizeof(v));
d[x]=;v[x]=;
q.push_back(x);
while(q.size())
{
int index=q.front();q.pop_front();
v[index]=;
for(int i=head[index];i;i=g[i].next){
int y=g[i].ver,z=g[i].edge;
if(d[y]>d[index]+z){
d[y]=d[index]+z;
if(!v[y]){
if(!q.empty()&&d[y]>=d[q.front()]) q.push_back(y);
else q.push_front(y);
v[y]=;
}
}
}
}
}

LLL优化:

LLL优化,即 Large Label Last  策略,使用 双端队列 进行优化。

一般用SLF+LLL可以优化50%左右,但是在竞赛中并不常用LLL优化。(所以我就懒得写了,这是从这个大佬那里嫖来的)

设队首元素为 k ,每次松弛时进行判断,队列中所有 dis 值的平均值为 x 。

若 dist[ k ] > x ,则将 k 插入到队尾,查找下一元素,直到找到某一个 k 使得 dis[ k ] <= x ,则将 k 出队进行松弛操作。

 void spfa(){
int u,v,num=;
long long x=;
list<int> q;
for(int i=;i<=n;i++){path[i]=MAX;vis[i]=false;}
path[s]=;
vis[s]=true;
q.push_back(s);
num++;
while(!q.empty()){
u=q.front();
q.pop_front();
num--;x-=path[u];
while(num&&path[u]>x/num){
q.push_back(u);
u=q.front();
q.pop_front();
}
vis[u]=false;
for(int i=head[u];i;i=a[i].next){
v=a[i].to;
if(relax(u,v,a[i].w)&&!vis[v]){
vis[v]=true;
if(!q.empty()&&path[v]<path[q.front()])q.push_front(v);
else q.push_back(v);
num++;x+=path[v];
}
}
}
for(int i=;i<=n;i++)printf("%d ",path[i]);
printf("\n");
}

DFS优化:

这种优化顾名思义,就是用dfs的思想代替bfs的思想来优化Bellman-Ford。

常常用于判断正/负环,时间复杂度可以达到O(m)(m是边)。思路是,我们每一次dfs的时候如果走回之前dfs过的点,那就是有环,除了这个dfs的标记,我们还可以打另一个vis数组记录更新过权值的节点,以后就不必重复更新,大大降低复杂度。

不过如果无环的话,那还是上面那两种优化稍微适用一点。代码比较短,但是不好扩展。

 inline bool spfa(int x)
{
dfs[x]=;
for(int i=head[x];i;i=g[i].next)
{
int y=g[i].ver,z=g[i].edge;
if(!v[y]||d[y]<d[x]+z){
if(dfs[y]) return ;
v[y]=;
d[y]=d[x]+z;
if(!spfa(y)) return ;
}
}
dfs[x]=;
return ;
}

SPFA的优化的更多相关文章

  1. SPFA 小优化*2

    /* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...

  2. HDU 1535 Invitation Cards(SPFA,及其优化)

    题意: 有编号1-P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费. 有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1. ...

  3. [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  4. 【最短路径】 SPFA算法优化

    首先先明确一个问题,SPFA是什么?(不会看什么看,一边学去,传送门),SPFA是bellman-ford的队列优化版本,只有在国内才流行SPFA这个名字,大多数人就只知道SPFA就是一个顶尖的高效算 ...

  5. SPFA队列优化

    spfa队列优化(用来求最短路) 实现方法: 1.存入图.可以使用链式前向星或者vocter. 2.开一个队列,先将开始的节点放入. 3.每次从队列中取出一个节点X,遍历与X相通的Y节点,查询比对   ...

  6. spfa + slf优化

    最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 . QwQ,所以就去学了一下优化 . slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我t ...

  7. 最短路--spfa+队列优化模板

    spfa普通版就不写了,优化还是要的昂,spfa是可以判负环,接受负权边和重边的,判断负环只需要另开一个数组记录每个结点的入队次数,当有任意一个结点入队大于点数就表明有负环存在 #include< ...

  8. CDOJ 1287 MC挖矿世界(Spfa+set优化)

    题目大意:原题链接 解题思路:此题要求多点最短距离,但是直接套用floyd会超时. 然后我们想直接从每一个点开始bfs就好了,但是还是会TLE,为什么呢? 因为你访问了很多次没有意义的地方,因为有些点 ...

  9. 初识费用流 模板(spfa+slf优化) 餐巾计划问题

    今天学习了最小费用最大流,是网络流算法之一.可以对于一个每条边有一个容量和一个费用(即每单位流的消耗)的图指定一个源点和汇点,求在从源点到汇点的流量最大的前提下的最小费用. 这里讲一种最基础也是最好掌 ...

  10. Gym - 100570B :ShortestPath Query(SPFA及其优化)

    题意:给定N点M边的有向图,每条边有距离和颜色,一条有效路径上不能有相邻的边颜色相同.现在给定起点S,多次讯问S到点X的最短有效距离. TLE思路:用二维状态dis(u,c)表示起点到u,最后一条边的 ...

随机推荐

  1. OpenGL学习笔记 之一 (基本的图形绘制)

    参考网址:http://www.cnblogs.com/FredCong/archive/2012/10/13/2722893.html #include <glut.h> #includ ...

  2. async/await小知识点

    一.使用async修饰的函数,返回的内容就是一个Promise,因此可以使用Promise对象所有的方法,如then等 二.在async函数中使用await是否会影响其他代码的执行,答案是:不会.

  3. JVM —— 类文件结构(下)

    简介 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的操作码(opcode)以及跟随其后的零至多个代表此操作所需参数的操作数(operand)所构成 虚拟机中许多指令并不包含操作数.只有 ...

  4. Excel逻辑运算函数

    Excel逻辑运算函数 1.FALSE和TRUE的使用 ​ 筛选出表中salary>6.gender为男.age>28至少满足这三个条件中的两个的数据 1.依次使用:=C2>6.=D ...

  5. python并发编程之协程(实践篇)

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对于单线程下,我们不可避免程序中出现io操作,但如果我们 ...

  6. Golang不会自动把slice转换成interface{}类型的slice

    目录 例子 原因 如何去实现 例子 我们时常会写一些interface,例如: type A interface{ Print() } type B struct { } func (b *B) Pr ...

  7. IntelliJ IDEA 之 配置JDK 的 4种方式

    一.新建项目前配置JDK 打开IDEA集成开发环境工具,点击:File--Project Structure,如下图 在打开的页面中,选择SDKs属性,并点击中间的加号+,选择JDK,如下图 在打开的 ...

  8. vue 数组对象取对象的属性: Cannot read property 'xxxx' of undefined

    {{ list[0].name }} list[0]没有定义 能正确打印出想要的结果,但就是报错,外面套个v-for就没错了 很费解 看到文章说是与异步有关,解决办法: <template v- ...

  9. html标签从.net framework转移到.net standard(.net core 2.2)时遇到的坑及填坑

    在原来的.net framework mvc中html的标签可以使用下面的方法 <select class="form-control" id="categoryi ...

  10. Linux查看系统及版本信息

    1.查看操作系统版本cat /proc/version 2.查看系统发行版cat /etc/issue 或cat /etc/redhat-release 3.查看系统内核信息uname -a