首页 > 其他分享 >Bellman_Ford

Bellman_Ford

时间:2024-05-12 21:08:17浏览次数:20  
标签:松弛 dist int 短路 Bellman Ford 负环 条边

基本上用不到的算法,和高精度一样,不常用,用到了又无可代替
常用于限制边数的最短路算法。

使用范围

可以处理任意边权的图,可以处理负环,可以判断负环。
时间复杂度 \(O(nm)\)。因为太慢了,在求最短路的时候基本用不到,但是它的优化版SPFA则大大优化了时间复杂度,算是最短路里最好用的算法,有很强的适应性。但近年来容易被卡。

中心思想

对每个点进行\(n - 1\)轮松弛
每一轮会遍历所有边,一共 \(n - 1\) 轮,时间复杂度也就是 \(O(nm)\)

正确性证明

第 \(1\) 轮松弛得到的是起点其他点,最多经过 \(1\) 条边的最短路径;第 \(n\) 轮得到的就是从起点到其他点,最多经过 \(n\) 条边点的最短路径。因为在 \(n\) 个点中,两个点之间的最短路径最多有 \(n - 1\) 条边,即对每个点最多进行 \(n - 1\) 轮松弛可以得到最短距离。
如果超过 \(n-1\) 轮还有边可以被松弛,那么说明有源点 \(S\) 点能到达的负环。

实操步骤

  1. 枚举每个点 \(u\)
  2. 枚举\(u\)连接着的边 \(w\) 和点 \(j\),并用和 \(dist[u]\) 和 \(w\) 更新 \(dist[j]\)
  3. 循环上面过程 \(n - 1\) 次

代码

代码和思想一样
但略有不同。

int bellman_ford(int S, int T)
{
    memset(dist, 0x3f, sizeof dist);
    dist[S] = 0;
    int k = n;
    while ( -- k)
    {
        memcpy(g, dist, sizeof dist);
        for (int u = 1; u <= n; u ++ )
            for (int i = h[u]; i != -1; i = ne[i])
            {
                int j = e[i];
                dist[j] = min(dist[j], g[u] + w[i]);
            }
    }
    return dist[T];
}

可以发现代码多了一个\(g\)数组,\(g\)是\(dist\)的复制数组,如果只是求最短路的话可以不用\(g\)代替\(dist\),但如果考虑限制经过\(k\)条边的话,必须加上。设当前为第\(k\)轮,那么\(g\)里面存的就是第\(k - 1\)轮的最短路,如果不这么做直接用\(dist\)更新,可能会出现连续更新的现象,即在这轮用刚更新完的\(dist\)去更新了其他点的\(dist\),就可能会打破边数的限制,在第k轮有经过\(k + n\)条边的最短路径,导致算法错误。因此,有必要加上这个\(g\)数组。

扩展

  1. 判断负环:据上面所说,我们最多 \(n-1\) 轮就能得出最短路径,也就说第 \(n\) 轮的时候不可能有边还能被松弛,如果有,则说明具有负环,可以无限松弛边长。这里还要注意一点,如果是发现第 \(n\) 轮没有边被松弛,不一定图上没有负环,可能只是源点 \(S\) 到不了而已,因此判断负环时应使用一个超级源点把所有点都连起来,边权为 \(0\) ,这样才能完美地找出负环。

标签:松弛,dist,int,短路,Bellman,Ford,负环,条边
From: https://www.cnblogs.com/blind5883/p/18188179

相关文章

  • 贝尔曼方程【Bellman Equation】
    强化学习笔记主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程,个人觉得赵老师的课件深入浅出,很适合入门.第一章强化学习基本概念第二章贝尔曼方程文章目录强化学习笔记一、状态值函数贝尔曼方程二、贝尔曼方程的向量形式三、动作值函数参考资料第......
  • 有限制的 bellman_ford 算法
    题目链接1.有限制的\(Bellman\_Ford\)时间复杂度:\(O(N*M)\)在传统的\(Bellman\_Ford\)中,可以处理边数不大于\(K\)条边的最短距离但我们只要加一条限制(实际上只多了两行代码)就可以实现求恰好等于\(K\)条边的最短距离具体的就在于其核心代码中:for(inti=0;i......
  • [Flink] Flink源码分析 : BoundedOutOfOrdernessTimestampExtractor
    0序言0.1缘起importorg.apache.flink.api.common.functions.MapFunction;importorg.apache.flink.api.java.tuple.Tuple;importorg.apache.flink.api.java.tuple.Tuple3;importorg.apache.flink.configuration.Configuration;importorg.apache.flink.configuration.......
  • 单源最短路径算法之bellman-ford
    单源最短路径算法之\(bellman-ford\)以边为研究对象单起点多终允许有负边权\(bellman-ford\)的工作原理假设\(n\)个点\(m\)条有向边的图,求\(s\)为起点的最短路条以\(s\)出发的最短路,最多包含\(n\)个点,\(n-1\)条边对于一条边\((x,y,w)\),\(y\)可能被\(x\)......
  • Bellman-ford 详解
    讲解  模板 第1题    bellman-ford练习查看测评数据信息给定一个n个点m条边的有向图,图中可能存在重边但不存在自环,边权可能为负数。请你求出从1号点到n号点最短距离,如果无法从1号点走到n号点,输出impossible。1≤n≤500,1≤m≤10000,任意边长的绝对值......
  • Bellman-Ford
    \(Bellman-Ford\)求单源最短路,可以判断有无负权回路(若有,则不存在最短路),时效性较好,时间复杂度\(O(VE)\)。\(Bellman-Ford\)算法是求解单源最短路径问题的一种算法。单源点的最短路径问题是指:给定一个加权有向图\(G\)和源点\(s\),对于图\(G\)中的任意一点\(t\),求从\(s\)到\(t\)......
  • C++U6-03-最短路算法2-bellmon-ford算法
    学习目标贝尔曼福特算法、SPFA 可以用来复习的B站视频:1、https://www.bilibili.com/video/BV1RK4y1d7ct?p=3&vd_source=5c960e1ede940bc5cab8ed42c8bdc9372、https://www.bilibili.com/video/BV18a4y1A7gv/?spm_id_from=333.999.0.0 SPFA算法是 Bellman-Ford算法 的队......
  • Bellman-Ford算法实现带有负权边的单源最短路
    Bellman-Ford算法对于Dijkstra算法,不妨给出这样一个例子graphLRA((A))-->|1|C((C))A-->|2|D((D))D-->|-4|C根据Dijkstra算法的流程,选取A为源点。更新与A邻接的顶点,有C和D。选取已更新顶点中距离A的最小值,显然选择边权为1的边所连接的顶点C,并将C收入最短路集合S中,此......
  • Bellman-Ford Algorithm 算法
    一、处理问题:负权值有向图单原点最短路径问题二、算法描述:假设带权值有向图中没有包含负权值环。定义一个距离数组,dist[0...n-1],dis[i]表示从原点到i的最短路径值初始化数组,假设一开始在原点src出发,终点为dst,那么dist[src]=0遍历所有的有向边,当前遍历边(a,b),a->b,权值为c,那么......
  • class065 A星、Floyd、Bellman-Ford与SPFA【算法】
    class065A星、Floyd、Bellman-Ford与SPFA【算法】2023-12-919:27:02算法讲解065【必备】A星、Floyd、Bellman-Ford与SPFAcode1A*算法模版//A*算法模版(对数器验证)packageclass065;importjava.util.PriorityQueue;//A*算法模版(对数器验证)publicclassCode01_AStarAlgori......