Open Caaaa-a opened 4 years ago
给定图$G(V, E)$(其中$V、E$分别为图$G$的顶点集与边集),源点$s$,数组$Distant[i]$记录从源点s到顶点i的路径长度,初始化数组$Distant[s]$为0;
以下操作循环执行至多$n-1$次,$n$为顶点数:
对于每一条边$e(u, v)$,如果存在$Distant[u] + w(u, v) < Distant[v]$的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组$Distant[n]$中记录的就是源点$s$到各顶点的最短路径长度。
*可知,Bellman-Ford算法寻找单源最短路径的时间复杂度为$O(VE)$.**
之所以需要第三部分的原因,是因为,如果存在从源点可达的权为负的回路。则 应为无法收敛而导致不能求出最短路径。
在更新路径的操作上,和迪杰斯特拉算法大同小异,但是不同于迪杰斯特拉算法,他不是选取最小的边进行选择,而是根据每一条边,依次对Distence数组进行更新,所以会访问很多访问过的点,借此重复不遗漏的更新距离数组,也就是规划起点到当前访问的相邻点的问题。
struct Node{ int v,dis; }; vector<Node> Adj[MAXV]; int n; int d[MAXV]; bool Bellman(int s){ fill(d,d+MAXV,INF); d[s]=0; for(int i=0;i<n-1;i++){ for(int u=0;u<n;u++){ for(int j=0;j<Adj[u].size();j++){ int v=Adj[u][j].v; int dis=Adj[u][j].dis; if(d[u]+dis<d[v]){ d[v]=d[u]+dis; } } } } for(int u=0;u<n;u++){ for(int j=0;j<Adj[u].size();j++){ int v=Adj[u][j].v; int dis=Adj[u][j].dis; if(d[u]+dis<d[v]){ return false; } } } return true; }
https://www.baidu.com/link?url=6V7op5fc4s6BVJFDBQdo9WUBBXg6ROAMLhCFRgWZ6R5ldgmiLNHZcuhePmjTM6rx&wd=&eqid=dee14139001aa83a000000065e2da5c2 极其详细的一篇博客
适用条件&范围:
Bellman-Ford算法的流程如下:
给定图$G(V, E)$(其中$V、E$分别为图$G$的顶点集与边集),源点$s$,数组$Distant[i]$记录从源点s到顶点i的路径长度,初始化数组$Distant[s]$为0;
以下操作循环执行至多$n-1$次,$n$为顶点数:
对于每一条边$e(u, v)$,如果存在$Distant[u] + w(u, v) < Distant[v]$的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组$Distant[n]$中记录的就是源点$s$到各顶点的最短路径长度。
*可知,Bellman-Ford算法寻找单源最短路径的时间复杂度为$O(VE)$.**
Bellman-Ford算法可以大致分为三个部分
之所以需要第三部分的原因,是因为,如果存在从源点可达的权为负的回路。则 应为无法收敛而导致不能求出最短路径。
与dij的比较
在更新路径的操作上,和迪杰斯特拉算法大同小异,但是不同于迪杰斯特拉算法,他不是选取最小的边进行选择,而是根据每一条边,依次对Distence数组进行更新,所以会访问很多访问过的点,借此重复不遗漏的更新距离数组,也就是规划起点到当前访问的相邻点的问题。
核心代码: