[算法学习]Bellman-Ford算法求最短路
Posted leafsblogowo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[算法学习]Bellman-Ford算法求最短路相关的知识,希望对你有一定的参考价值。
OAO dijkstra算法在复杂度方面是十分优秀的,但是其最大弊端就是无法处理带负权的图
(因为是基于已经被更新过的距离源点的边必然已经达到了最短路的这个事实 来采取贪心策略来求得最短路
而有负权路存在时,这个基础不在成立。)
这个时候就要请出Bellman-Ford算法了
(正确性证明:https://oi-wiki.org/graph/shortest-path/)
贴个代码emm:
#include<bits/stdc++.h> using namespace std; //Bellman-Ford 队列优化 const int maxn = 1e5 + 5; struct edge{ int to,w; }; bool book[maxn]; int dis[maxn]; queue<int> q; vector<edge> edges[maxn]; int n,m,s; int u,v,w; int main(){ cin>>n>>m>>s; while(m--){ scanf("%d%d%d", &u, &v, &w); edges[u].push_back(edge{v,w}); } fill(dis,dis+n+1,0x3f3f3f3f); dis[s] = 0; book[s] = 1; q.push(s); while(!q.empty()){ int t = q.front(); q.pop(); for(int i = 0; i < edges[t].size(); i++){ if(dis[edges[t][i].to] > dis[t] + edges[t][i].w){ dis[edges[t][i].to] = dis[t] + edges[t][i].w; if(!book[edges[t][i].to]){ book[edges[t][i].to] = 1; q.push(edges[t][i].to); } } } book[t] = 0; } for(int i = 1; i <= n; i++) cout<<dis[i]<<" "; return 0; }
对每个队列中的点,对所有的出边所对应的终点到源点的距离进行更新
再将被更新路径的点放入队列
直至没有点可以被放入队列(即所有点到源点的距离都最近)
然后Bellman-Ford的队列优化(也就是SPFA)是一种不稳定的优化,最差还是会退化至Bellman-Ford的O(NM)的
(emm也就是说特别构造的数据可以把SPFA卡到T掉,所以没有负权的话还是打dijkstra比较好)
以上是关于[算法学习]Bellman-Ford算法求最短路的主要内容,如果未能解决你的问题,请参考以下文章