bellman-ford算法

Bellman-Ford模板

耗尽温柔 提交于 2020-03-20 10:06:02
Bellman-Ford 算法流程分为三个阶段: (1) 初始化:将除源点外的所有顶点的最短距离估计值 d[v] ←+∞, d[s] ←0; (2) 迭代求解:反复对边集 E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次) (3) 检验负权回路:判断边集 E 中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回 false ,表明问题无解;否则算法返回 true ,并且从源点可达的顶点 v 的最短距离保存在 d[v] 中。 算法描述如下: Bellman-Ford(G,w,s) : boolean // 图 G ,边集 函数 w , s 为源点 1 for each vertex v ∈ V(G) do //初始化 1阶段 2 d[v] ←+∞ 3 d[s] ←0; //1阶段结束 4 for i=1 to |v|-1 do //2阶段开始,双重循环。 5 for each edge(u,v) ∈E(G) do //边集数组要用到,穷举每条边。 6 If d[v]> d[u]+ w(u,v) then //松弛判断 7 d[v]=d[u]+w(u,v) //松弛操作 2阶段结束 8 for each edge(u,v) ∈E(G) do 9 If d[v]> d[u]+ w(u,v) then 10 Exit

单源最短路 Bellman-Ford算法

不打扰是莪最后的温柔 提交于 2020-02-15 19:12:31
1 // 单源最短路问题 2 // Bellman-Ford算法 3 // 复杂度O(V*E) 4 5 //! 可以判断负圈 6 7 8 #include <cstdio> 9 #include <iostream> 10 11 // 最大边数 12 const int max_E=10000+2; 13 // 最大定点数 14 const int max_N=1000+2; 15 const int INF=1e9; 16 17 using namespace std; 18 // 定义边结构体edge 19 struct edge 20 { 21 int from,to,cost; 22 }; 23 24 edge es[max_E]; 25 26 int d[max_N]; 27 int N,E; 28 29 void shortest_path(int s) 30 { 31 for(int i=0;i<N;++i) 32 { 33 d[i]=INF; 34 } 35 d[s]=0; 36 37 while(true) 38 { 39 bool update=false; 40 // 每次更新都要遍历所有的边 41 for(int i=0;i<E;++i) 42 { 43 edge e=es[i]; 44 if(d[e.from]!=INF && d[e.to]>d[e

最短路--Bellman-Ford

假如想象 提交于 2019-12-06 08:34:39
Bellman-Ford 算法思想 枚举n次,每次枚举每一条边,如果dis[u] > dis[v]+w[v][u],则dis[u] = dis[v]+w[v][u],如果图没有负环则最多跑n-1次,否则可以一直跑下去 模板 bool Bellman_Ford(int s) { memset(dis,inf,sizeof dis); dis[s] = 0; bool flag; for(int i = 1; i <= n; i++) //n个点 { flag = false; for(int j = 0; j < m; j++) //m条边 { int x = edge[j].u; int y = edge[j].v; int z = edge[j].w; if(dis[y] > dis[x]+z) { dis[y] = dis[x]+z; flag = true; } } if(!flag) break; if(i==n && flag) return false;//存在负环 } return true; } 例题 参考博客 https://www.cnblogs.com/CLAYzhan/articles/11621448.html 来源: https://www.cnblogs.com/hezongdnf/p/11972680.html

图论 - Bellman-Ford算法

混江龙づ霸主 提交于 2019-11-30 16:14:49
Bellman-Ford Dijkstra算法虽好,但是不能解决带有负边权的图. 而利用Bellman-Ford可以完美的解决最短路和负边权的问题 朴素Bellman-Ford算法 w[i] 权值 u[i]->v[i] 存储边集 默认大家已经会了邻接表存储,如果有没有学会邻接表存储的小伙伴要先去学习一些邻接表的存储操作哦! ^_^ 核心代码: for(int k = 1; k <= n-1; k++) for(int i = 1; i <= m; i++) if(dis[v[i]] > dis[u[i]] + w[i]) dis[v[i]] = dis[u[i]] + w[i]; 显然其时间复杂度为O(m*n) 分析过程 下面列出一个具体的松弛过程可帮助大家更好的理解代码: 完整代码: #include <iostream> #include <algorithm> using namespace std; int main() { int dis[10], n, m, u[10], v[10], w[10]; int inf = 9999999; cin >> n >> m; //读入边 for (int i = 1; i <= m; i++) cin >> u[i] >> v[i] >> w[i]; //初始化dis数组 fill(dis, dis + 10, inf);

最短路径之Bellman-Ford算法——动态规划

删除回忆录丶 提交于 2019-11-28 08:18:09
文章目录 1.算法原理 2. 算法流程 3.Bellman-Ford算法的实现 4.单源单目的地的特殊写法 参考资料 Bellman-Ford算法 主要针对 带有负值的单源最短路径问题 ,当有向图带有其权小于0的边的时候,不能使用 迪杰斯特拉算法 ,但是只要不是带负权的回路,我们依然可以使用 Bellman-Ford算法 。 1.算法原理 Bellman-Ford算法 的核心思想是 动态规划 ,即我们需要定义 子问题的状态 和 动态规划递归式 。 讨论前提 如果图中共有 n n n 个顶点,则所有的最短路径最多只有 n − 1 n-1 n − 1 条边。 如果一条路径具有 n n n 条以上的边,则一定有环路(参考图的最小生成树性质)。 而由于环路的权值都不小于0,则去掉环路后的路径会更短,所以 两个连通的顶点之间不存在含有环路的最短路径,且最多有n-1条边 。 动态规划公式 所以,我们像迪杰斯特拉算法一样关注 最短路径的长度 , 令 d ( v , k ) d(v,k) d ( v , k ) 表示源点 s s s 到顶点 v v v 且最多含有 k k k 条边的最短路径,于是 d ( v , n − 1 ) d(v,n-1) d ( v , n − 1 ) 就是我们的目标。 首先,对于 k = 0 k=0 k = 0 有, d ( v , 0 ) = { 0 , v = s