SPFA算法模板

SPFA是队列优化后的Bellman-Ford,用于求带负权边的最短路,然而传说中O(k*n)的复杂度好像是错误的。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<string>
 5 #include<set>
 6 #include<queue>
 7 using namespace std;
 8 #define INF 0x3f3f3f3f
 9 #define M(a, b) memset(a, b, sizeof(a))
10 const int maxn = 1000 + 5;
11
12 struct Edge {
13     int from, to, dist;
14 };
15
16 struct SPFA {
17     int d[maxn], cnt[maxn], p[maxn];
18     int n, m;
19     bool inq[maxn];
20     vector<int> G[maxn];
21     vector<Edge> edges;
22
23     void init(int n) {
24         this->n = n;
25         for (int i = 1; i <= n; ++i) G[i].clear();
26         edges.clear();
27     }
28
29     void AddEdge(int from, int to, int dist) {
30         edges.push_back(Edge{from, to, dist});
31         int m = edges.size();
32         G[from].push_back(m-1);
33     }
34
35     bool spfa(int s) {
36         M(d, INF); M(cnt, 0); M(inq, 0);
37         d[s] = 0;
38         queue<int> q;
39         q.push(s);
40         inq[s] = true;
41         while (!q.empty()) {
42             int u = q.front(); q.pop();
43             inq[u] = false;
44             for (int i = 0; i < G[u].size(); ++i) {
45                 Edge &e = edges[G[u][i]];
46                 if (d[e.to] > d[u] + e.dist) {
47                     d[e.to] = d[u] + e.dist;
48                     p[e.to] = G[u][i];
49                     if (!inq[e.to]) {
50                         q.push(e.to); inq[e.to] = true;
51                         if (++cnt[e.to] > n) return false;
52                     }
53                 }
54             }
55         }
56         return true;
57     }
58
59 };
60
61 SPFA solver;
62
63 int main() {
64     int n, m, a, b, c;
65     while(cin >> m >> n) {
66         solver.init(n);
67         while(m--) {
68             cin >> a >> b >> c;
69             solver.AddEdge(a, b, c);
70             solver.AddEdge(b, a, c);
71         }
72         solver.spfa(1);
73         cout << solver.d[n] << endl;
74     }
75     return 0;
76 }
时间: 2024-08-10 23:29:51

SPFA算法模板的相关文章

(最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: /** *floyd算法 */ void floyd() { int i, j, k; for (k = 1; k <= n; ++k) {//遍历全部的中间点 for (i = 1; i <= n; ++i) {//遍历全部的起点 for (j = 1; j <= n; ++j) {//遍历

spfa 算法模板 可求带负权边的最短路

它是队列优化的Bellman-Ford算法. 优化的原理是:下一次松弛操作时被更新dis的点其实与上一次被更新的点有关!如果上一次被更新的点有一条边指向某点V,那么在下一次,点V就是可能被更新dis的点. 和 Bellman-Ford 算法一样,它可以用来求带负权边的最短路,如果存在一个从源点可以到达的权重为负值的环路,则返回false表示无解决方案,因为可以不断在这个环路中循环使总代价越来越小:如果不存在则返回true. #include<iostream> #include<algo

最小费用流spfa算法模板(pascal)

以前写过,现在的码风与以前有些变化,主要是用数组模拟邻接表存图,以前是用指针存图. 以前的博文:http://www.cnblogs.com/Currier/p/6387732.html 洛谷可评测. 传送门:https://www.luogu.org/problem/show?pid=3381 1 program rrr(input,output); 2 const 3 inf=123456789; 4 type 5 etype=record 6 t,c,w,next,rev:longint;

单元最短路径算法模板汇总(Dijkstra, BF,SPFA),附链式前向星模板

一:dijkstra算法时间复杂度,用优先级队列优化的话,O((M+N)logN)求单源最短路径,要求所有边的权值非负.若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 设road[i][j]表示相邻的i到j的路长U集合存储已经求得的到源点最短路径的节点,S集合表示还没求得的节点dis[i]表示i到源节点(设为0)的最短路径vis[i]=1表示i节点在U集合中 刚开始dis[0]=0,vis[0]=1;dis[i]=maxn,vis[i]=0;for 1 to

[知识点]SPFA算法

// 此博文为迁移而来,写于2015年4月9日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vx93.html 1.前言 最短路算法有很多种,类似于Floyd和Dijkstra都是很早之前就学了的.其实每种最短路算法有各自的优势.Floyd适合于跑完全图,但是效率太慢(O(n3)).Dijkstra适合于跑没有负权的图,效率为O(n2).而今天介绍的SPFA算法,是有一位中国人——段凡丁所提出来的(其实我很想吐个槽.

bellman-ford算法模板

有SPFA模板,bellman-ford模板显然是多余的. var e:array[1..maxe]of record a,b,w:longint;end; { 距源点s距离 } dis:array[1..maxn]of longint; { 前驱 } pre:array[1..maxn]of longint; m,n,s:longint; procedure relax(u,v,w:longint); begin if dis[u]+w<dis[v] then begin dis[v]:=di

hdu 1217 Arbitrage (spfa算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目大意:通过货币的转换,来判断是否获利,如果获利则输出Yes,否则输出No. 这里介绍一个STL中的map容器去处理数据,map<string,int>V,M; 现在我目前的理解是将字符串转换成数字,然后就是根据spfa的模板找最短路了..哇哈哈( ⊙o⊙ )哇 1 #include <iostream> 2 #include <cstdio> 3 #include

最短路:spfa算法

板子补完计划绝赞继续中( 这篇博客就来写一写spfa(这我居然板子都打错了一次,我太弱啦!) 先来看一下定义:(引自http://blog.csdn.net/juststeps/article/details/8772755) 首先说明,SPFA是一种单源最短路径算法,所以以下所说的"某点的最短路径长度",指的是"某点到源点的最短路径长度". 我们记源点为S,由源点到达点i的"当前最短路径"为D[i],开始时将所有D[i]初始化为无穷大,D[S]

SPFA算法及其应用和优化

by mps [问题引入] 又是一年春运时,因为睡懒觉而导致抢不到票的你,只能打车回家了,而无疑会消耗许多钱财(黑车...),为了尽可能的节省钱,你希望走的是最短路,路途中会经过n个城市,而你每次经过两个城市之间的高速公路时,都会损耗Ci元,假设其中包含了所有的价钱(邮费,过桥费之类的),你现在在1号城市,希望到达n号城市去,请问最少花费是多少? [输入描述] 第一行,n,m,表示有n个城市,m条高速公路 第二行至第m+1行,每行三个数u,v,w,表示u城市到达v城市的耗费为w元(均为有向边)