关于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. 题目描述 如题,给出一个有向图,请输出从某一点出 ...
随机推荐
- 【西北师大-2108Java】第六次作业成绩汇总
[西北师大-2108Java]第六次作业成绩汇总 作业题目 面向对象程序设计(JAVA) 第8周学习指导及要求 实验目的与要求 (1)掌握接口定义方法: (2)掌握实现接口类的定义要求: (3)掌握实 ...
- 《2018:skymind.ai 发布了一份非常全面的开源数据集》
这是一份非常全面的开源数据集,你,真的不想要吗? 近期,skymind.ai 发布了一份非常全面的开源数据集.内容包括生物识别.自然图像以及深度学习图像等数据集,现机器之心将其整理如下:(内附链接 ...
- cartographer 3D运行录制rosbag包
目录: 1.运行多线激光雷达: 2.运行IMU: 3.录制rosbag包: 4.配置cartographer: 5.查看地图: 1.运行多线激光雷达: 主要是测试雷达是否正在运行,确认雷达点云topi ...
- centos安装nodejs并配置生产环境,基于pm2
安装nodejs和yarn的命令: curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum. ...
- 易优CMS:arcview基础用法
[基础用法] 名称:arcview 功能:获取单条文档数据 语法: {eyou:arcview aid='文档ID'} <a href="{$field.arcurl}"&g ...
- ubuntu 16.04上源码编译和安装cgal并编写CMakeLists.txt | compile and install cgal on ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/39ab7ed9/,欢迎阅读最新内容! compile and install cgal on ubuntu 16.04 Guide ...
- Java设计模式:Flyweight(享元)模式
概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...
- asp.net 使用NPOI读取excel文件
asp.net 使用NPOI读取excel文件内容 NPOI下载地址:NPOI public class ExcelHelper { /// <summary> /// 读取Excel文件 ...
- SQL server已经设置为单用户模式,还是无法做分离、属性设置等操作
https://www.cnblogs.com/xingyunqiu/p/10336938.html SQL server已经设置为单用户模式,Sql server还原失败数据库正在使用,无法获得对数 ...
- VS中怎样对C#项目进行单元测试
场景 SpringBoot+Junit在IDEA中实现查询数据库的单元测试: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/927 ...