spfa算法

初学SPFA

狂风中的少年 提交于 2019-11-28 00:49:33
SPF A 算法是 Bellman-Ford 算法的队列优化算法的别称,在国际上被称为“队列优化的 Bellman-Ford 算法”,仅在中国被称为 SPFA 算法。也就是说,这是 Bell-man Ford 的升级版( 虽说本人也不会 Bellman-Ford )。 SPFA 通常用于求含负权边的单源最短路径,以及判负权环。 SPFA 的时间复杂度一般为 O(km) 。但由于这种算法的过于玄学,当有人故意卡你时,可能会变成 O(nm), 所以请慎用。 例题 题目描述 小Q非常喜欢在自己的国家旅行。小Q所在的国家有N座城市,分别编号为1~n,小Q所在的城市编号为1。小Q现在想知道从他所在的城市出发,到其他N-1个城市的最短路程分别是多少? 输入 第一行两个整数N,M(1<=n<=1000,1<=M<=100000),分别表示小Q所在的国家有N座城市以及城市间有M条单向道路。 接下来M行,每行三个整数x,y,len(1<=x,y<=n,1<=len<=100000)表示从城市x去到城市y需要走len这么多路程。 输入可能存在重边 输入 一共N-1行,每行一个整数,第i个整数表示小Q从城市1到城市(i+1)的最短路程。如果不能到达输出-1 样例输出 4 4 1 2 3 2 3 4 1 3 2 2 4 1 样例输出 3 2 4 代码实现 #include<iostream>

负环详解(暂无题目推荐)

只谈情不闲聊 提交于 2019-11-27 11:58:50
什么是负环? 顾名思义,就是一个所有边的边权和为负数的环 出现负环会怎么样? 我们知道,一般情况下,图上的最短路都是确定的。但是一旦图上有一个负环, \(s\) 到 \(t\) 的最短路就会不远千里的去覆盖上这个环(只要能够到达),并且不厌其烦的走上一遍又一遍。由于负环的边权和是负的,并且它是一个环,也就是说走一遍和走无数遍都停留在进入的那个点。那么最短路每经过一次这个负环,这个费用都会缩小一点,如果经过了无数次,也就是无穷小,也就是 不存在最短路 。当然这里有一个限定,就是每个点经过的次数不能超过 \(1\) 次。 既然负环的影响这么大,那么就要引出我们的下一个问题了。 怎么判定负环? 相信大家都学过至少两种最短路的计算方法,而且一定也都会 \(dijkstra\) 和 \(SPFA\) 这两种算法(如果不会的请先去学习SPFA再来观看此博客)。花开两朵,各表一枝。我们这里只谈 \(SPFA\) 。大家都知道, \(SPFA\) 的判定方式就是不断地收紧每个点到起点的最短路径,每次都不一定会收到最紧,但只要有解,最终一定会收成最紧(这也正是它这么好卡的原因,一点一点的,能不慢吗)。我们前面提到过,如果存在负环,那么最短路会不断缩小至无穷小。那么这里我们就可以应用它的这一特点。在 \(SPFA\) 中,每个点最短被其他 \(n-1\) 个点各收紧一次,如果被收紧了 \(n\) 次

题解小合集——第八弹

喜夏-厌秋 提交于 2019-11-27 04:55:05
(转载于 我的洛谷博客 ) 索引: 第一题:P2564 生日礼物 第二题:P3084 照片 第三题:P4878 布局 第四题:P2736 “破锣摇滚”乐队 第五题:P4568 飞行路线 第六题:P1284 三角形牧场 第七题:P3959 宝藏 第八题:P1197 星球大战 第九题:P1337 平衡点 第十题:P1325 雷达安装 第一题:P2564 生日礼物 题解思路:单调队列(尺取法) 这题和P1638 逛画展 很像,唯一的区别就是可能同一个位置上可能都有多个"彩珠" 然而有多个"彩珠"这点有和P2698 花盆 这题一样 所以我们可以继承两题的思路,用P1638的单调队列和P2698里的结构体来解决这个题。显然,我们的结构体要记录两个数据:位置,种类。然后我们对位置排序,以便于维护单调序列。 我们用一个指针l指向区间的最左端的珠子,然后遍历所有珠子(不用去循环右端点,因为在彩带上会有地方没有珠子,把右端点放在没有珠子的地方是没有意义的),每增加一颗i种类的珠子,kind[i]就记录i种类的珠子的最近出现的位置。如果又找到了一颗和 区间最左端的珠子 相同的珠子,那么最左端的珠子就没有存在的必要了,把它出队即可。当区间包含所有种类的珠子时,我们更新并记录最优答案,在遍历完之后输出即可。 请结合代码加深理解…… #include<cstdio> #include<cstring>

最短路径

痴心易碎 提交于 2019-11-27 00:27:50
没有用的话qaq : Ummmm…图论的大部分知识本来早就有学过,只是一直没有写成博文来梳理,但既然上了qbxt DP图论就写一篇来总结下, 主要是来听DP的,但…由于太菜的原因,DP听得天花乱坠QWQ 图中的最短路算法分为单源最短路算法(dijkstra,Bellman-food,spfa)和多源最短路算法(floyd),单源最短路算法是求图上一点到其他任意一点的最短路径,多源最短路算法是求图上任意两点之间的最短路。 一,多源最短路算法 Floyd弗洛伊德算法,运用了动态规划的思想,用邻接矩阵存储,期初将从任何一点到其他所有点的最短路都置成正无穷,然后输入时修改有的权值,其主要思想是动态规划,在最外围枚举点,看看有没有一个点可以更新两点之间的最短路。 代码简单易懂 memset(dis,0x3f,sizeof(dis)); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 时间复杂度为O(n^3 ),空间复杂度为O(n^2),时间和空间均不是很优,一般较少采用,一般在求n范围较小的多源最短路题中才有出现。 可以适用于有负权边的情况,可以判断图的连通性,可以传递闭包 二,多源最短路算法 1,Dijkstra a

C--最短路 ----邻接表存储及SPFA算法

▼魔方 西西 提交于 2019-11-26 22:20:41
C--最短路 Time Limit: 7000MS Memory Limit: 65536KB Problem Description 给出一个带权无向图,包含n个点,m条边。求出s,e的最短路。保证最短路存在。 Input 多组输入。 对于每组数据。 第一行输入n,m(1<= n && n<=5*10^5,1 <= m && m <= 2*10^6)。 接下来m行,每行三个整数,u,v,w,表示u,v之间有一条权值为w(w >= 0)的边。 最后输入s,e。 Output 对于每组数据输出一个整数代表答案。 Example Input 3 1 1 2 3 1 2 Example Output 3 思路: 由于节点的数据范围过大,因此无法利用二维数组存储路径,此时需要使用连接表存储路径。 SPFA算法: 1.可以解决有负权值的情况。 2.利用队列进行松弛操作。 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #define inf 0x3f3f3f3f using namespace std; struct node { int id; int wi; } a,b;

HDOJ 2544 - 最短路 SPFA算法

自闭症网瘾萝莉.ら 提交于 2019-11-26 17:41:14
因为QM混乱的原因,白白WA了好几次 AC 0MS 228K 1 #include <queue> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <memory.h> 5 using namespace std; 6 7 const int maxn = 101 ; 8 const int INF = 0x3F3F3F3F ; 9 10 int a, b, c, nNum, mNum; 11 int g[maxn][maxn], QM[maxn], dist[maxn]; 12 13 int SPFA() 14 { 15 int x; 16 queue < int > q; 17 18 q.push( 1 ); 19 QM[ 1 ] = 1 , dist[ 1 ] = 0 ; 20 21 while (! q.empty()) 22 { 23 x = q.front(); 24 q.pop(); 25 QM[x] = 0 ; /* Took Away */ 26 27 for ( int i= 1 ; i<=nNum; ++ i) 28 { 29 if (dist[i] > dist[x]+ g[x][i]) 30 { 31 dist[i] = dist[x] + g[x][i]; /* change the

SPFA算法模板(刘汝佳版)--Wormholes POJ - 3259

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-26 10:35:26
一直觉得紫书代码比较精炼,就照着紫书上不完整的SPFA算法写了一道判断是否有负权边的题,题目链接: https://vjudge.net/problem/POJ-3259 ,细节看代码 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #include<iostream> 6 #include<vector> 7 #include<set> 8 #include<queue> 9 #define MAXN 500100 10 #define INF 0x3f3f3f3f 11 using namespace std; 12 typedef long long ll; 13 int n,m,w; 14 struct node 15 { 16 int from,to,cost; 17 node(int a,int b,int c):from(a),to(b),cost(c){} 18 };///边的结构体 19 vector<int>G[MAXN];///G[i]中的元素代表以i为起点的边 20 vector<node>edges;///存放所有的边 21 bool inq[MAXN]; 22 int d[MAXN],cnt[MAXN]; 23 bool SPFA