SPFA+SLF+LLL
关于SLF优化
朴素SPFA使用常规队列(FIFO)更新距离,并没有考虑优化出队顺序(dis值小的优先出队)可以在一开始就把各个点的dis值限值小,从而避免大量的松弛操作,从而提高效率。这就是SLF(Small Label First)。
实现方式很简单,常规队列替换为双端队列(deque),对于一个要加入的点u,如果dis[u]<dis[Q.front()],u就放入队首,否则放入队尾。
此外还有LLL(Large Label first)优化,思路是对每个要出队的元素u,比较dis[u]和队列中所有dis值的平均值,如果dis[u]大,那么将它弹出放到队尾,取队首元素再重复判断,直达存在dis[u]小于平均值。发现没有,LLL和SLF的目的是一样的。
当然,可以把这两种优化组合起来。
STL双端队列
- 全称:“double-ended queue”,deque是双端数组,而vector是单端的
- 在操作方式上和vector相似
- 可以随机存取元素(用
[]操作符或at()方法) - 头部和尾部添加或移除元素非常快,在中部插入或删除元素比较慢
- 需要添加头文件
<deque>
//定义
deque<int> dq1; //一个存放int的deque容器
deque<double> dq2; //一个存放float的deque容器
deque<string> de3; //一个存放string的deque容器。
//添加移除
dq1.push_back(elem); //在容器尾部添加一个元素
dq1.push_front(elem); //在容器头部插入一个元素
dq1.pop_back(); //删除容器最后一个元素
dq1.pop_front(); //删除容器第一个元素
//存取
cout<<dq1.at(pos); //返回pos位置的元素,如果pos越界,抛出out_of_range异常
cout<<dq1[pos]; //返回pos位置的元素,如果pos越界,一般情况下RE
dq1[pos]=1;
cout<<dq1.front(); //返回第一个元素
cout<<dq1.back(); //返回最后一个元素
//迭代器
dq1.begin(); //返回容器中第一个元素的迭代器
dq1.end(); //返回容器中最后一个元素之后的迭代器
dq1.rbegin(); //返回容器中倒数第一个元素的迭代器
dq1.rend(); //返回容器中倒数最后一个元素之后的迭代器
//大小
dq1.size(); //返回容器中元素的个数
dq1.empty(); //判断容器是否为空
dq1.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
dq1.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
//带参数构造
deque<int> dqx(dq1.begin(), dq1.end()); //用dq1 [beg, end)区间中的元素初始化dqx
deque<int> dqy(n, elem); //用n个elem初始化dqx
deque<int> dqz(dq1); //拷贝构造函数,用dq1初始化dqz
//赋值
deque<int> dqm, dqn;
dqm.assign(dq1.begin(), dq1.end()); //将dq1 [beg, end)区间中的数据拷贝给dqm
dqn.assign(n, elem); //将n个elem拷贝赋值给dqn
dqn=dqm; //整体拷贝
dqn.swap(de1); //整体交换
//插入
dq1.insert(pos, elem); //pos位置插入elem
dq1.insert(pos, n, elem); //pos位置插入n个elem
dq1.insert(pos, beg, end); //pos位置插入迭代器[begin, end)之间的元素
//删除
dq1.clear(); //清空
dq1.erase(beg, end); //删除[beg,end)区间的元素,返回下一个元素的位置
dq1.erase(pos); //删除pos位置的元素,返回下一个元素的位置
//SPFA+SLF
#include<iostream>
#include<cstdio>
#include<cstring>
#include<deque>
using namespace std;
const int maxn=1e4+5, maxm=5e5+5, INF=2147483647;
int dis[maxn], v[maxn], n, m, s;
struct edge{
int t, w; edge *nxt;
edge(int to, int len, edge *next){ t=to, w=len, nxt=next; }
};
edge *h[maxn];
void add(int x, int y, int z){ h[x]=new edge(y, z, h[x]); }
void SPFA(int s)
{
for(int i=1; i<=n; i++) dis[i]=(i==s) ? 0 : INF;
deque<int> Q; //Q为双端队列
Q.push_back(s), v[s]=1;
while(!Q.empty())
{
int x=Q.front(); Q.pop_front(); v[x]=false; //v数组用以标记点i是否在队列中
for(edge *p=h[x]; p; p=p->nxt)
if(dis[p->t]>dis[x]+p->w)
{
dis[p->t]=dis[x]+p->w;
if(!v[p->t])
{
v[p->t]=1;
if(Q.empty() || dis[p->t]>dis[Q.front()]) Q.push_back(p->t);
else Q.push_front(p->t);
}
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &s);
for(int i=1, x, y, z; i<=m; i++) scanf("%d%d%d", &x, &y, &z), add(x,y,z);
SPFA(s);
for(int i=1; i<=n; i++) printf("%d ",dis[i]);
return 0;
}
//SPFA+SLF+LLL
#include<iostream>
#include<cstdio>
#include<cstring>
#include<deque>
using namespace std;
const int maxn=1e4+5, maxm=5e5+5, INF=2147483647;
int dis[maxn], v[maxn], n, m, s;
struct edge{
int t, w; edge *nxt;
edge(int to, int len, edge *next){ t=to, w=len, nxt=next; }
};
edge *h[maxn];
void add(int x, int y, int z){ h[x]=new edge(y, z, h[x]); }
void SPFA(int s)
{
int cnt=0, sum=0; //cnt为队列中元素个数,sum为队列中dis值总和
for(int i=1; i<=n; i++) dis[i]=(i==s) ? 0 : INF;
deque<int> Q; //Q为双端队列
Q.push_back(s), v[s]=1, cnt=1;
while(!Q.empty())
{
int x=Q.front();
while(cnt*dis[x]>sum) //取出来,放后去,直到找到一个比平均值小的点
{
Q.pop_front();
Q.push_back(x);
x=Q.front();
}
Q.pop_front();
cnt--, sum-=dis[x], v[x]=false; //出队后,更新队列大小及队列dis值之和
for(edge *p=h[x]; p; p=p->nxt)
if(dis[p->t]>dis[x]+p->w)
{
dis[p->t]=dis[x]+p->w;
if(!v[p->t])
{
v[p->t]=1;
if(Q.empty() || dis[p->t]>dis[Q.front()]) Q.push_back(p->t);
else Q.push_front(p->t);
cnt++, sum+=dis[p->t]; //入队后,更新队列大小及队列dis值之和
}
}
}
}
int main()
{
scanf("%d%d%d", &n, &m, &s);
for(int i=1, x, y, z; i<=m; i++) scanf("%d%d%d", &x, &y, &z), add(x,y,z);
SPFA(s);
for(int i=1; i<=n; i++) printf("%d ",dis[i]);
return 0;
}
SPFA+SLF+LLL的更多相关文章
- SPFA+SLF+LLL优化模板
#include<algorithm> #include <iostream> #include <cstdlib> #include <cstring> ...
- Dijkstra、Dij + heap、Floyd、SPFA、 SPFA + SLF Template
Dijkstra in Adjacency matrix : int Dijkstra(int src,int tec, int n){ ]; ]; memset(done,,sizeof(done) ...
- [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化
Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...
- POJ - 3268 Silver Cow Party SPFA+SLF优化 单源起点终点最短路
Silver Cow Party One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to ...
- spfa + slf优化
最近在练习费用流 , 不是要用spfa吗 ,我们教练说:ns学生写朴素的spfa说出去都让人笑 . QwQ,所以就去学了一下优化 . slf优化就是双向队列优化一下,本来想用lll优化,可是优化后我t ...
- 2013成都邀请赛J称号||HDU4725 The Shortest Path in Nya Graph(spfa+slf最短的优化)
职务地址:HDU 4725 这题卡了好长时间了,建图倒是会建,可是不会最短路的算法优化,本以为都须要堆去优化的,打算学了堆之后再来优化.可是昨晚CF的一道题..(那题也是不优化过不了..)然后我就知道 ...
- 初识费用流 模板(spfa+slf优化) 餐巾计划问题
今天学习了最小费用最大流,是网络流算法之一.可以对于一个每条边有一个容量和一个费用(即每单位流的消耗)的图指定一个源点和汇点,求在从源点到汇点的流量最大的前提下的最小费用. 这里讲一种最基础也是最好掌 ...
- SPFA的两个优化:SLF与LLL
先举出个例题:洛谷P3371 [模板]单源最短路径 一眼扫去:最短路径. spfa不接受反驳... 附上代码: #include<iostream> #include<algorit ...
- 【最短路径】 常用算法图解+1376:信使(msner)六解
进入图之后,最短路径可谓就是一大重点,最短路径的求法有很多种,每种算法各有各的好处,你会几种呢?下面来逐个讲解. 1 floyed算法 1)明确思想及功效:在图中求最短路还是要分开说的,分别是单源最短 ...
随机推荐
- Proxmox VE登陆的时候提示没有有效的订阅You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options.
问题描述: 用的是免费版的,所以每次都提示这个没有有效的订阅挺烦的 解决方法: 修改文件/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib. ...
- 【实战代码】PHP实现读取一个1G的文件大小
本文地址:http://www.cnblogs.com/aiweixiao/p/7535351.html 欢迎关注我的微信公众号哈 “ 程序员的文娱情怀” http://t.cn/RotyZtu [背 ...
- 【Python 06】汇率兑换1.0-1(IPO与字符串转数字)
1.案例描述 设计一个汇率换算器程序,功能是将外币换算成人民币. 2.案例分析 将问题划分为输入.处理及输出三部分(IPO) 3.上机实验 rmb_str_value = input('请输入人民币( ...
- DISK 100% BUSY,谁造成的?(ok)
iostat等命令看到的是系统级的统计,比如下例中我们看到/dev/sdb很忙,如果要追查是哪个进程导致的I/O繁忙,应该怎么办? # iostat -xd ... Device: rrqm/s wr ...
- LOJ #2542. 「PKUWC 2018」随机游走(最值反演 + 树上期望dp + FMT)
写在这道题前面 : 网上的一些题解都不讲那个系数是怎么推得真的不良心 TAT (不是每个人都有那么厉害啊 , 我好菜啊) 而且 LOJ 过的代码千篇一律 ... 那个系数根本看不出来是什么啊 TAT ...
- leetcode 203. Remove Linked List Elements 、83. Remove Duplicates from Sorted List 、82. Remove Duplicates from Sorted List II(剑指offer57 删除链表中重复的结点)
203题是在链表中删除一个固定的值,83题是在链表中删除重复的数值,但要保留一个:82也是删除重复的数值,但重复的都删除,不保留. 比如[1.2.2.3],83题要求的结果是[1.2.3],82题要求 ...
- mac 利用svn下载远程代码出现Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo.
终端输出的信息:Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. ...
- vue diff 算法学习
function updateChildren (parentElm, oldCh, newCh, insertedVnodeQueue, removeOnly) { let oldStartIdx ...
- Golang 入门系列(四)如何理解interface接口
前面讲了很多Go 语言的基础知识,包括go环境的安装,go语言的语法等,感兴趣的朋友,可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category ...
- ConcurrentHashMap 与 Hashtable
粘贴复制于:https://blog.csdn.net/lzwglory/article/details/79978788 集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构 ...