图论记录之Bellman-Ford 算法

算法思想

java 复制代码
迭代n次 即循环n次
	遍历所有边,对于每一条边(a,b,v)表示a->b的权值为v
	若从起点到b的距离大于从起点到a的距离+a到b的距离就更新
	这里代码中的体现在于dist[b] = min(dist[b],dist[a]+v])
	没了

循环n次,对于所有的边一定满足
dist[b] <= dist[a]+w,这东西叫做三角不等式,更新一次叫做松弛操作看弹幕的时候看到了一个差分约束系统挺高大上的

适用情况

适用于有负权边的最短路问题,但对于负权回路没有办法,但可以判定有没有负权回路

边数限制也可以用,注意若有边数限制,需要加上一个备份数组,防止发生串联更新,关于这个串联更新的意思就是说,a点被更新了,拿着更新后的a点去更新其他点,而其他点需要的是更新前的a点的值,

负权回路与最短路径的存在性的相关性问题

只要负权回路不在最短路径上,那么就存在最短路径

比如1->2 2是终点,存在负权回路,但是也存在最短路径

判定有没有负权回路

它可以判定,但是一般不用这个算法,用SPFA,因为时间复杂度大

迭代了k次,k的含义从1号点经过不少于k条边走到每个点的最短路的距离,若第n迭代的时候又更新了某条边的话,存在一条边数是大于等于n的最短路径,那么就可以判定是有负权回路,

我的理解就是 n个点的最短路径只有n-1条边,若大于等于了n可以判定有环,而且还是更新后的(也就是说当前值要比上一次的值要小)

时间复杂度

设边数为m,那么时间复杂度就是O(nm),n是迭代的次数

java 复制代码
迭代n次 即循环n次
	遍历所有边,对于每一条边(a,b,v)表示a->b的权值为v
	若从起点到b的距离大于从起点到a的距离+a到b的距离就更新
	这里代码中的体现在于dist[b] = min(dist[b],dist[a]+v])
	没了

代码

java 复制代码
import java.util.Arrays;
import java.util.Scanner;

class Edge{
    int start,end,weight;
    public Edge(int start,int end,int weight){
        this.start = start;
        this.end  = end;
        this.weight = weight;
    }
}
public class Main{
    static int n,m,k,max=(int)1e8;
    static int[] dist;
    static Edge[] edges;
    static int bellman_ford(){
        dist[1] =0;
        for(int i=0;i<k;i++){
        	//这个备份数组的作用是防止发生串联更新
            int[] backup = Arrays.copyOf(dist,dist.length);
            for(Edge item: edges){
                if(dist[item.end]>dist[item.start]+item.weight){
                    dist[item.end] = Math.min(dist[item.end],backup[item.start]+ item.weight);
                }
            }
        }
        if(dist[n]>=max/2)
            return max/2;
        return dist[n];
    }
    public static void main(String[] args) {
        Scanner s=  new Scanner(System.in);
        n = s.nextInt();
        m = s.nextInt();
        k = s.nextInt();
        edges = new Edge[n];
        dist = new int[n+1];
        Arrays.fill(dist,max);
        for(int i=0;i<n;i++)
            edges[i] = new Edge(s.nextInt(),s.nextInt(),s.nextInt());
        int res = bellman_ford();
        if(res==max/2)
            System.out.println("impossible");
        else
            System.out.println(res);
        s.close();
    }
}
相关推荐
先吃饱再说14 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰17 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术18 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六21 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术1 天前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize1 天前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队2 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode