SPFA的优化
【为什么要优化】
关于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的优化的更多相关文章
- SPFA 小优化*2
/* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...
- HDU 1535 Invitation Cards(SPFA,及其优化)
题意: 有编号1-P的站点, 有Q条公交车路线,公交车路线只从一个起点站直接到达终点站,是单向的,每条路线有它自己的车费. 有P个人早上从1出发,他们要到达每一个公交站点, 然后到了晚上再返回点1. ...
- [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- 【最短路径】 SPFA算法优化
首先先明确一个问题,SPFA是什么?(不会看什么看,一边学去,传送门),SPFA是bellman-ford的队列优化版本,只有在国内才流行SPFA这个名字,大多数人就只知道SPFA就是一个顶尖的高效算 ...
- SPFA队列优化
spfa队列优化(用来求最短路) 实现方法: 1.存入图.可以使用链式前向星或者vocter. 2.开一个队列,先将开始的节点放入. 3.每次从队列中取出一个节点X,遍历与X相通的Y节点,查询比对 ...
- spfa + slf优化
最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 . QwQ,所以就去学了一下优化 . slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我t ...
- 最短路--spfa+队列优化模板
spfa普通版就不写了,优化还是要的昂,spfa是可以判负环,接受负权边和重边的,判断负环只需要另开一个数组记录每个结点的入队次数,当有任意一个结点入队大于点数就表明有负环存在 #include< ...
- CDOJ 1287 MC挖矿世界(Spfa+set优化)
题目大意:原题链接 解题思路:此题要求多点最短距离,但是直接套用floyd会超时. 然后我们想直接从每一个点开始bfs就好了,但是还是会TLE,为什么呢? 因为你访问了很多次没有意义的地方,因为有些点 ...
- 初识费用流 模板(spfa+slf优化) 餐巾计划问题
今天学习了最小费用最大流,是网络流算法之一.可以对于一个每条边有一个容量和一个费用(即每单位流的消耗)的图指定一个源点和汇点,求在从源点到汇点的流量最大的前提下的最小费用. 这里讲一种最基础也是最好掌 ...
- Gym - 100570B :ShortestPath Query(SPFA及其优化)
题意:给定N点M边的有向图,每条边有距离和颜色,一条有效路径上不能有相邻的边颜色相同.现在给定起点S,多次讯问S到点X的最短有效距离. TLE思路:用二维状态dis(u,c)表示起点到u,最后一条边的 ...
随机推荐
- 记录git 软件库
https://github.com/phpredis/phpredis redis扩展 https://github.com/tecnickcom/tcpdf 生成PDF 后续......
- [CF788B]Weird journey_欧拉回路
Weird journey 题目链接:http://codeforces.com/contest/788/problem/B 数据范围:略. 题解: 我们发现就是要求,把每条无向边拆成两条无向边,其中 ...
- json 和对象互相转换
json 和对象互相转换 导入 Jar 包: import com.fasterxml.jackson.databind.ObjectMapper; Maven 地址: <!-- https:/ ...
- Fiddler之手机抓包
1.Fiddle设置端口,Tools->Options->Connections, 2.手机设置代理服务器: 注意:要保证手机和PC电脑IP在同一个网段(或者同一个网关) (1).安卓手机 ...
- Jmeter 跨线程组传递参数 之两种方法(转)
终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直 ...
- PAT甲级 图 相关题_C++题解
图 PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目 目录 1122 Hamiltonian Cycle (25) 1126 Eulerian P ...
- python爬虫框架scrapy 豆瓣实战
Scrapy 官方介绍是 An open source and collaborative framework for extracting the data you need from websit ...
- SAS学习笔记14 利用SAS绘制地图(二)
笔记9讲过利用SAS绘制地图,这次接着讲 用中国各地(不含港澳台)的平均湿度数据来绘制地图 在地图上标出地名 宏%maplabel有9个参数,依次为:地图文件名.包含区域名称的数据集文件.输出的注释数 ...
- Django 中 app_name (应用命名空间) 和 namespace (实例命名空间) 的区别
转自:https://www.jianshu.com/p/404500a0408a 补充理解: 先把官网上对应用命名空间(app_name)和实例命名空间(namespace)的解释贴上: app_n ...
- MySQL 子查询(四)子查询的优化、将子查询重写为连接
MySQL 5.7 ref ——13.2.10.10优化子查询 十.子查询的优化 开发正在进行中,因此从长远来看,没有什么优化建议是可靠的.以下列表提供了一些您可能想要使用的有趣技巧.See also ...