当前位置: 首页 > article >正文

Day60 图论part10

今天大家会感受到 Bellman_ford 算法系列在不同场景下的应用。

建议依然是:一刷的时候,能理解 原理,知道Bellman_ford 解决不同场景的问题 ,照着代码随想录能抄下来代码就好,就算达标。 二刷的时候自己尝试独立去写,三刷的时候 才能有一定深度理解各个最短路算法。

Bellman_ford 队列优化算法(又名SPFA)

代码随想录

import java.util.*;

public class Main{
    public static void main (String[] args) {
        //对所有的边松弛n-1次
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        List<List<Edge>> graph = new ArrayList<>(n+1);
        
        for(int i = 0; i <= n; i++){
            graph.add(new ArrayList<>());
        }
        
        for(int i = 0; i < m; i++){
            int start = scanner.nextInt();
            int end = scanner.nextInt();
            int val = scanner.nextInt();
            graph.get(start).add(new Edge(start, end, val));
        }
        
        int[] minDist = new int[n+1];
        Arrays.fill(minDist, Integer.MAX_VALUE);
        minDist[1] = 0;
        
        Deque<Integer> queue = new ArrayDeque<>();
        boolean[] isVisited = new boolean[n+1];
        queue.add(1);
        isVisited[1] = true;
        
        while(!queue.isEmpty()){
            int start = queue.remove();
            //取出队列的时候,要取消标记,这样保证有其他路径对该节点进行更新,我们只要保证节点不被重复加入队列即可
            isVisited[start] = false;
            
            for(Edge edge : graph.get(start)){
                if(minDist[start] + edge.val < minDist[edge.end]){
                    minDist[edge.end] = minDist[start] + edge.val;
                   if(!isVisited[edge.end]){
                    queue.add(edge.end);
                    isVisited[edge.end] = true;
                    }
                } 
                
            }
        }
        
        if(minDist[n] == Integer.MAX_VALUE){
            System.out.println("unconnected");
        }else{
            System.out.println(minDist[n]);
        }
    
    }
}

class Edge{
    int start;
    int end;
    int val;
    
    public Edge(int start, int end, int val){
        this.start = start;
        this.end = end;
        this.val = val;
    }
}

总结

1.普通的Bellman_ford算法其实是每次都对所有的边都进行一次松弛,但其实但真正有效的松弛,是基于已经计算过的节点在做的松弛。所以我们每次松弛只需要基于上一次松弛更新过的节点,以该节点作为出发节点对连接的边就行。那我们就可以使用队列来记录上一次松弛更新过的节点,把这些节点依次加入到队列里面,然后又取出来处理。

2.队列里面存储的是每条边的起点,我们需要根据这些起点,找到边,所以这样传统的邻接表来存储图是最好的List<List<Edge>> graph = new ArrayList<>(n+1);

3.然后在while循环里面,还有一些地方和之前的处理不一样,我们需要使用isVisited[]数组来判断节点是否在队列里面&#x


http://www.kler.cn/a/459020.html

相关文章:

  • Android 系统 ActivityManager 系统层深度定制
  • 【SOC 芯片设计 DFT 学习专栏 -- DFT 为何需要在综合之后插入】
  • 在C语言基础上的C++(深入理解类和对象)
  • SqlSession的线程安全问题源码分析
  • 虚拟机Centos下安装Mysql完整过程(图文详解)
  • 【基础代数】概述与导论
  • 【OTA】论文笔记--《智能网联汽车整车OTA功能设计研究》智能网联汽车OTA系统设计分析报告
  • nuscenes数据集pkl文件转txt
  • 网络安全概念详解
  • 最新版Edge浏览器加载ActiveX控件技术——alWebPlugin中间件V2.0.28-迎春版发布
  • Kafka 性能提升秘籍:涵盖配置、迁移与深度巡检的综合方案
  • MIPI相关
  • 家政预约小程序数据库设计
  • 【Mysql】Mysql/Mariadb开启binlog日志
  • STM32 高级 物联网通讯之蓝牙通讯
  • Spring AI OpenAI Spring Boot Starter 底层原理详解与技术演示
  • CSS 过渡动画效果
  • C#高级篇 反射和属性详解【代码之美系列】
  • Path-of-Thoughts:将“思维链“升级为“思维图“,三阶段框架取代单一推理,提升大模型复杂关系推理准确性至88.2%与效率提升5%
  • WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)
  • java里classpath都包含哪些范围?
  • afsim源码编译生成出现错误解决方法
  • 单片机中运行多个定时器
  • 【Docker】离线安装 Docker
  • SELECT 语句用法大全:数据库查询的核心力量
  • 【网络安全实验室】基础关实战详情