Bellman_ford求最短路可以说这个算法在某些地方和dijkstra还是有些相似的,它们的松弛操作基本还是一样的只不过dijkstra以图中每个点为松弛点对其相连接的所有边进行松弛操作
而Bellman_ford就是省去了找松弛点的操作,而是每次将n个点进行m次操作(一共m条边),那么和dijkstra一样的我们进行n次循环即最坏的情况我们要对整个图进行n次松弛(虽然对没有优化的Bell_ford始终都要跑n次),(这篇博客不讲对于Bellman_ford的优化)
Bellman_ford算法和dijkstra算法相差其实并不大,不过是Bellman_ford是以边来进行松弛的就是我们跑n次循环每一遍又进行m次操作对整个图进行松弛那么n次过后我们一定可以保证每一个点的dis值一定是最小的,但我们可以发现这样即使当dis值已经是最小时我们还是要对其操作即使其结果也没有什么变化因此我们就浪费了时间(因为Bellman_ford算法不能像dijkstra那样确定最小的dis值)
Bellman_ford核心代码
void Bellman_ford() { for(int k=1;k<=n-1;k++)//因为最后一次没有必要所以没有必要进行(某些情况例外) { for(int i=1;i<=m;i++)//松弛操作 { if(dis[edges[i].to]>dis[edges[i].from]+edges[i].w) dis[edges[i].to]=dis[edges[i].from]+edges[i].w; } } return; }
图解:
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <iomanip> #include <cstring> using namespace std; #define in cin #define out cout typedef int insert; const insert INF=0x3f3f3f3f; const insert N=1e4+100; insert n,m,startpoint,dis[N]; struct Node { insert from,to,w; }edges[N]; void inital_value() { memset(dis,INF,sizeof(dis)); for(int i=1;i<=m;i++) in>>edges[i].from>>edges[i].to>>edges[i].w; dis[startpoint]=0; } void Bellman_ford() { for(int k=1;k<=n-1;k++) { for(int i=1;i<=m;i++) { if(dis[edges[i].to]>dis[edges[i].from]+edges[i].w) dis[edges[i].to]=dis[edges[i].from]+edges[i].w; } } return; } int main() { in>>n>>m>>startpoint; inital_value(); Bellman_ford(); for(int i=1;i<=n;i++) out<<startpoint<<"-->"<<i<<" "<<dis[i]<<endl; return 0; }