图论记录之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();
    }
}
相关推荐
我不是QI1 小时前
DES 加密算法:核心组件、加解密流程与安全特性
经验分享·算法·安全·网络安全·密码学
前端小刘哥1 小时前
新版视频直播点播EasyDSS平台,让跨团队沟通高效又顺畅
算法
明月(Alioo)2 小时前
机器学习入门,无监督学习之K-Means聚类算法完全指南:面向Java开发者的Python实现详解
python·算法·机器学习
叶梅树2 小时前
从零构建A股量化交易工具:基于Qlib的全栈系统指南
前端·后端·算法
lingran__2 小时前
算法沉淀第三天(统计二进制中1的个数 两个整数二进制位不同个数)
c++·算法
MicroTech20252 小时前
微算法科技MLGO推出隐私感知联合DNN模型部署和分区优化技术,开启协作边缘推理新时代
科技·算法·dnn
小冯记录编程3 小时前
深入解析C++ for循环原理
开发语言·c++·算法
chenchihwen4 小时前
深度解析RAG系统中的PDF解析模块:Docling集成与并行处理实践
python·算法·pdf
做科研的周师兄6 小时前
【机器学习入门】7.4 随机森林:一文吃透随机森林——从原理到核心特点
人工智能·学习·算法·随机森林·机器学习·支持向量机·数据挖掘
Sunsets_Red6 小时前
差分操作正确性证明
java·c语言·c++·python·算法·c#