SPFA算法及其应用和优化

by mps

【问题引入】

又是一年春运时,因为睡懒觉而导致抢不到票的你,只能打车回家了,而无疑会消耗许多钱财(黑车...),为了尽可能的节省钱,你希望走的是最短路,路途中会经过n个城市,而你每次经过两个城市之间的高速公路时,都会损耗Ci元,假设其中包含了所有的价钱(邮费,过桥费之类的),你现在在1号城市,希望到达n号城市去,请问最少花费是多少?

【输入描述】

第一行,n,m,表示有n个城市,m条高速公路

第二行至第m+1行,每行三个数u,v,w,表示u城市到达v城市的耗费为w元(均为有向边)

【数据范围】

对于20%的数据,n≤100,m≤1,000

对于50%的数据,n≤1,000, m≤1,000

对于100%的数据,n≤10,000,m≤10,000

【分析】

题目其实并不难,一个最短路的裸模板题目

但是数据却让初学者犯了难,很明显出题人的意思是这样的:

对于20分,是留给只会floyd的人

对于50分,是留给会dijkstra或者bellman_ford

对于100分,是留给会heap+dijkstra或者spfa+(slf/lll)

本文着重介绍SPFA以及优化(SLF/LLL)

参考资料:http://www.cnblogs.com/pony1993/archive/2012/09/07/2675654.html

SPFA算法是基于Bellman_ford算法的改进,Bellman_ford算法的大致模板如下:

for(i=1->v)

for(j=1->e)

if(u,v (-E 且 e(u,v)+δu<δv)

δv=e(u,v)+δu

时间复杂度O(ve)

对于数据较大的情况(比如说例题)会TLE,所以我们需要优化

那么如何优化呢?

我们发现,每次没有必要松弛m条边,只需要松弛与当前节点有关的边即可,但是又会有些节点脱离了拓扑关系,所以我们可以采用队列/栈来维护拓扑关系

这样我们的时间复杂度就降到了O(VK) 一般情况下k<2,但没有绝对性的证明而且有针对性数据,所以除非迫不得已采用SPFA(事实上出现迫不得已的情况就是因为出题人想让你用SPFA....)否则尽可能的采用高效率的Dijkstra,实在不行弄个堆优化,要知道,堆优化的dijkstra是可以超过SPFA的(而且绝对稳定)

而SPFA用手动队列写起来有点烦,而我们C++的福利就在于STL为我们提供了绝对具有安全性的队列,但是耗时间太长了,不过我们可以采用许多优化来弥补

具体有4种优化方案(1,3只能选1种)

(1)SLF

设当前队头为i,即将入队的点j,若δi≥δj,则直接将j入对头,否则入队尾,效率提升10%~20%,需要数据结构双端队列

(2)LLL(效率低下,这里不赘述)

(3)Prq

采取优先队列,每次存储距离小的,效率提升20%~30%,与堆优化的dijkstra并肩

(4)Math(适用于判断负权环)

由于K的取值不定,有可能会非常多,所以对于判断负权环就只能无奈的TLE了,这时我们可以用随机数生成一个在题目条件下的最大最极端的数据,然后不断地缩小N

(补充:判断是否具有负权环只需判断每个点的入队次数是否>N)

到最后原本O(1000*1000)的算法可能优化为O(1000*3)的算法,不过本优化适宜RP好或者数学学霸使用

推荐练习题:

NOIP2014D2T2寻找道路

USACO 欢乐派对

USACO 骑马修栅栏

另:最短路学好对以后的网络流问题有极大的帮助

时间: 2024-11-05 17:33:19

SPFA算法及其应用和优化的相关文章

spfa算法详解

program: #include<cstdio> using namespace std; struct node {int x; int value; int next; }; node e[60000]; int visited[1505],dis[1505],st[1505],queue[1000]; int main() { int n,m,u,v,w,start,h,r,cur; freopen("c.in","r",stdin); freo

最短路径--SPFA 算法

适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一定存在.当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点. 算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G.我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计

最短路算法 :Bellman-ford算法 &amp; Dijkstra算法 &amp; floyd算法 &amp; SPFA算法 详解

 本人QQ :2319411771   邮箱 : [email protected] 若您发现本文有什么错误,请联系我,我会及时改正的,谢谢您的合作! 本文为原创文章,转载请注明出处 本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 很早就想写一下最短路的总结了,但是一直懒,就没有写,这几天又在看最短路,岁没什么长进,但还是加深了点理解. 于是就想写一个大点的总结,要写一个全的. 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并

POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23064   Accepted: 4987 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

EOJ 1848 你是ACM吗? 用二叉堆优化dijkstra + spfa算法的学习

Description  随着中国经济的腾飞,中国的物流产业迎来了发展的春天.特别是在上海这样一个拥有广阔国内腹地的国际化大都市,物流业以空前的速度膨胀. 当然是大蛋糕就会吸引许多馋嘴猫,馋嘴猫多了就会有残酷的竞争.当大量资金流入物流产业时,KOP 集团为了稳坐在国内物流业的第一把交椅,决定对现行的运输方案进行改良,以减少自己的成本同时使其它竞争者知难而退. 作为世界100强的KOP集团当然知道要找到最优运输方案,肯定得靠数学和算法很好的软件工程师,于是他们理所当然地找到华东师范大学软件学院.决

关于SPFA算法的优化方式

关于SPFA算法的优化方式 这篇随笔讲解信息学奥林匹克竞赛中图论部分的求最短路算法SPFA的两种优化方式.学习这两种优化算法需要有SPFA朴素算法的学习经验.在本随笔中SPFA朴素算法的相关知识将不予赘述. 上课! No.1 SLF优化(Small Label First) 顾名思义,这种优化采用的方式是把较小元素提前. 就像dijkstra算法的堆优化一样.我们在求解最短路算法的时候是采取对图的遍历,每次求最小边的一个过程,为了寻找最小边,我们需要枚举每一条出边,如果我们一上来就找到这个边,那

POJ 1511 Invitation Cards 【最短路,spfa算法,Dijkstra算法堆优化】

Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 25219   Accepted: 8346 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They wan

SPFA算法

适用范围:给定的图存在负权边,这时类似Dijkstra等算法便没有了用武之地,而Bellman-Ford算法的复杂度又过高,SPFA算法便派上用场了. 我们约定有向加权图G不存在负权回路,即最短路径一定存在.当然,我们可以在执行该算法前做一次拓扑排序,以判断是否存在负权回路,但这不是我们讨论的重点. 算法思想:我们用数组d记录每个结点的最短路径估计值,用邻接表来存储图G.我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计

Cocos2d-x 地图行走的实现2:SPFA算法

上一节<Cocos2d-x 地图行走的实现1:图论与Dijkstra算法> http://blog.csdn.net/stevenkylelee/article/details/38408253 本节实践另一种求最短路径算法:SPFA 1.寻路算法实现上的优化 上一节我们实现的Dijkstra用了一个哈希表来保存搜索到的路径树.如果能用直接的访问的方式,就不要用哈希表,因为直接访问的方式会比哈希表更快.我们修改一下图顶点的数据结构.如下: /* 图顶点 */ class Vertex { fr