利用SPFA算法求最短路

该算法由Bellman-Ford算法演变过来,首先介绍一下Bellman-Ford算法

最短路最多经过n-1个点,可以用n-1轮松弛操作来得到

for(int i=0;i<n;i++)
    d[i]=INF;
d[0]=0;
for(int k=0;k<n-1;k++)
for(int i=0;i<m;i++)  //检查每条边
{
    int x=u[i];
    int y=v[i];
    if(d[x]<INF)
        d[y]=min(d[y],d[x]+w[i]);
} 

当然这个算法我没有实际应用过,而是一直在用它的优化算法,利用队列代替前面的循环检查

SPFA最坏时间复杂度仍然为O(nm),但是有人分析其时间复杂度为O(km),k为每个点入队次数,正确性未知

SPFA和Bellman-Ford都可以检测负环但是只有后者可以输出负环

下面给出邻接表实现的SPFA算法,可以求出单源最短路。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int maxn=10005;
 5 const int maxm=500005;
 6 const int INF=0x7fffffff;
 7 //
 8 int n,m,s;
 9 //
10 int g[maxn];
11 struct point
12 {
13     int t,w,next;
14 }e[maxm];
15 int d[maxn];
16 //
17 int tot=0;
18 void addedge(int a,int b,int c)
19 {
20     tot++;
21     e[tot].t=b;
22     e[tot].w=c;
23     e[tot].next=g[a];
24     g[a]=tot;
25 }
26 //
27 int q[maxn];
28 bool v[maxn];
29 void spfa(int x0)
30 {
31     for(int i=1;i<=n;i++)
32     d[i]=(i==x0?0:INF);
33     int h=0,t=1;
34     q[t]=x0;
35     while(h!=t)
36     {
37         h=h%maxn+1;
38         int x=q[h];
39         v[x]=false;
40         for(int tmp=g[x];tmp;tmp=e[tmp].next)
41         {
42             if(d[e[tmp].t]>d[x]+e[tmp].w)
43             {
44                 d[e[tmp].t]=d[x]+e[tmp].w;
45                 if(!v[e[tmp].t])
46                 {
47                     v[e[tmp].t]=true;
48                     t=t%maxn+1;
49                     q[t]=e[tmp].t;
50                 }
51             }
52         }
53     }
54 }
55 int main()
56 {
57     cin>>n>>m>>s;
58     for(int i=1;i<=m;i++)
59     {
60         int x,y,z;
61         cin>>x>>y>>z;
62         addedge(x,y,z);
63     }
64     spfa(s);
65     for(int i=1;i<=n;i++)
66         cout<<d[i]<<" ";
67     return 0;
68 }

原文地址:https://www.cnblogs.com/aininot260/p/9272894.html

时间: 2024-11-10 23:21:01

利用SPFA算法求最短路的相关文章

spfa算法求最短路

给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数. 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible. 数据保证不存在负权回路. 输入格式 第一行包含整数n和m. 接下来m行每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z. 输出格式 输出一个整数,表示1号点到n号点的最短距离. 如果路径不存在,则输出”impossible”. 数据范围 1≤n,m≤1051≤n,m≤105,图中涉及边长绝对值均不超过10000

hdu1869六度分离,spfa实现求最短路

就是给一个图,如果任意两点之间的距离都不超过7则输出Yes,否则 输出No. 由于之前没写过spfa,无聊的试了一下. 大概说下我对spfa实现的理解. 由于它是bellmanford的优化, 所以之前会bf的理解起来,可能会比较容易. 它是这样子的,你弄一个队列, 先打一个起点进去,之后求出的到各点的最短路, 都是由这个点出发的. 然后开始迭代,直至队列为空, 在迭代的过程中, 首先从队列里面拿一个点出来, 然后标记一下,说明这个点不在队列里面, 然后开始枚举所有点,进行松弛化, 松弛化的过程

利用Kruskal算法求最小生成树解决聪明的猴子问题 -- 数据结构

题目:聪明的猴子 链接:https://ac.nowcoder.com/acm/problem/19964 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地 表还是被大水淹没着,部分植物的树冠露在水面上.猴子不会游泳,但跳跃能力比较强,它们仍然可以在露出水面 的不同树冠上来回穿梭,以找到喜欢吃的果实.现在,在这个地区露出水面的有N棵树,假设每棵树本身的直径都 很小,可以忽略不计.我们在这块区域上建立直角坐标系,则每一棵树的位置由其所对应的坐标表

poj 2139 Floyd-Warshall算法求最短路

题意:不想说,这个题意思了,含糊不清=-= Dijkstra算法,无法计算有负边的图,原因是有负边的图存在是会打乱Dijkstra算法的前提,当前优先队列取出点的距离为起点到该点的最小距离,因为如果后面有负边这个距离会更小.除此之外Bellman-Ford算法和Floyd-warshall算法都可以计算有负边的图,且判断是否有负圈. Floyd-Warshall算法:该算法用到了动态规划归约的思想来求任意两点间的最短距离.令:d[k][i][j]为最短路可以包括0到k的所有顶点时i到j的最短距离

[算法学习]Bellman-Ford算法求最短路

OAO dijkstra算法在复杂度方面是十分优秀的,但是其最大弊端就是无法处理带负权的图 (因为是基于已经被更新过的距离源点的边必然已经达到了最短路的这个事实 来采取贪心策略来求得最短路 而有负权路存在时,这个基础不在成立.) 这个时候就要请出Bellman-Ford算法了 (正确性证明:https://oi-wiki.org/graph/shortest-path/) 贴个代码emm: #include<bits/stdc++.h> using namespace std; //Bellm

利用Stoer-Wagner算法求无向图最小割

直接给出算法描述和过程实现: 算法步骤: 1. 设最小割cut=INF, 任选一个点s到集合A中, 定义W(A, p)为A中的所有点到A外一点p的权总和. 2. 对刚才选定的s, 更新W(A,p)(该值递增). 3. 选出A外一点p, 且W(A,p)最大的作为新的s, 若A!=G(V), 则继续2. 4. 把最后进入A的两点记为s和t, 用W(A,t)更新cut. 5. 新建顶点u, 边权w(u, v)=w(s, v)+w(t, v), 删除顶点s和t, 以及与它们相连的边. 6. 若|V|!=

POJ1860——Currency Exchange(BellmanFord算法求最短路)

Currency Exchange DescriptionSeveral currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points sp

dijkstra算法求最短路

艾兹格·W·迪科斯彻 (Edsger Wybe Dijkstra,1930年5月11日~2002年8月6日)荷兰人. 计算机科学家,毕业就职于荷兰Leiden大学,早年钻研物理及数学,而后转为计算学.曾在1972年获得过素有计算机科学界的诺贝尔奖之称的图灵奖,之 后,他还获得过1974年 AFIPS Harry Goode Memorial Award.1989年ACM SIGCSE计算机科学教育教学杰出贡献奖.以及2002年ACM PODC最具影响力论文奖. 艾兹格·W·迪科斯彻(Edsger

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

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