Day52 | dijkstra(堆优化版)Bellman_ford 算法

news2024/9/20 14:49:29

dijkstra(堆优化版)

题目

47. 参加科学大会

47. 参加科学大会(第六期模拟笔试)

题目描述

小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。

小明的起点是第一个车站,终点是最后一个车站。然而,途中的各个车站之间的道路状况、交通拥堵程度以及可能的自然因素(如天气变化)等不同,这些因素都会影响每条路径的通行时间。

小明希望能选择一条花费时间最少的路线,以确保他能够尽快到达目的地。

输入描述

第一行包含两个正整数,第一个正整数 N 表示一共有 N 个公共汽车站,第二个正整数 M 表示有 M 条公路。 

接下来为 M 行,每行包括三个整数,S、E 和 V,代表了从 S 车站可以单向直达 E 车站,并且需要花费 V 单位的时间。

输出描述

输出一个整数,代表小明从起点到终点所花费的最小时间。

思路

  1. 初始化一个网格 grid 来存储各个节点之间的距离,初始值设为 Integer.MAX_VALUE 表示不可达。
  2. 读取输入来填充网格中的实际距离。
  3. 创建两个数组 minDist 和 visited 分别用来记录从起始点到每个节点的最短距离以及节点是否已经被访问。
  4. 使用循环遍历所有的节点,每次选择一个距离起点最近且未被访问过的节点。
  5. 更新其他未访问节点的最短距离,如果通过当前节点可以达到更短的距离,则更新这个距离。
  6. 输出从起点到终点的最短距离,如果不可达则输出 -1

代码

import java.util.*;

class Edge {
    int to;  // 邻接顶点
    int val; // 边的权重

    Edge(int to, int val) {
        this.to = to;
        this.val = val;
    }
}

class MyComparison implements Comparator<Pair<Integer, Integer>> {
    @Override
    public int compare(Pair<Integer, Integer> lhs, Pair<Integer, Integer> rhs) {
        return Integer.compare(lhs.second, rhs.second);
    }
}

class Pair<U, V> {
    public final U first;
    public final V second;

    public Pair(U first, V second) {
        this.first = first;
        this.second = second;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();

        List<List<Edge>> grid = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            grid.add(new ArrayList<>());
        }

        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            grid.get(p1).add(new Edge(p2, val));
        }

        int start = 1;  // 起点
        int end = n;    // 终点

        // 存储从源点到每个节点的最短距离
        int[] minDist = new int[n + 1];
        Arrays.fill(minDist, Integer.MAX_VALUE);

        // 记录顶点是否被访问过
        boolean[] visited = new boolean[n + 1];

        // 优先队列中存放 Pair<节点,源点到该节点的权值>
        PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>(new MyComparison());

        // 初始化队列,源点到源点的距离为0,所以初始为0
        pq.add(new Pair<>(start, 0));

        minDist[start] = 0;  // 起始点到自身的距离为0

        while (!pq.isEmpty()) {
            // 1. 第一步,选源点到哪个节点近且该节点未被访问过(通过优先级队列来实现)
            // <节点, 源点到该节点的距离>
            Pair<Integer, Integer> cur = pq.poll();

            if (visited[cur.first]) continue;

            // 2. 第二步,该最近节点被标记访问过
            visited[cur.first] = true;

            // 3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)
            for (Edge edge : grid.get(cur.first)) { // 遍历 cur指向的节点,cur指向的节点为 edge
                // cur指向的节点edge.to,这条边的权值为 edge.val
                if (!visited[edge.to] && minDist[cur.first] + edge.val < minDist[edge.to]) { // 更新minDist
                    minDist[edge.to] = minDist[cur.first] + edge.val;
                    pq.add(new Pair<>(edge.to, minDist[edge.to]));
                }
            }
        }

        if (minDist[end] == Integer.MAX_VALUE) {
            System.out.println(-1); // 不能到达终点
        } else {
            System.out.println(minDist[end]); // 到达终点最短路径
        }
    }
}

易错点

如果起始点和结束点相同,或者图中没有直接或间接连接起始点和结束点的路径,那么 minDist[end] 将保持为 Integer.MAX_VALUE,这是正确的行为。但是,在实际应用中需要注意边界情况,例如输入数据的有效性验证。

Bellman_ford 算法

题目

城市间货物运输 I

94. 城市间货物运输 I

思路

  1. 定义 Edge 类:创建一个内部类 Edge 来表示图中的每条边,包含起点 from、终点 to 和边的权重 val

  2. 输入处理:从标准输入读取节点数 n 和边数 m,然后读取每条边的信息并将其存储在 List<Edge> 中。

  3. 初始化距离数组:创建一个数组 minDist 来存储从起始节点(默认为 1)到每个节点的最短距离。所有节点的初始距离都设为 Integer.MAX_VALUE,除了起始节点设为 0。

  4. 松弛操作:执行 n - 1 次松弛操作来更新 minDist 数组。每次迭代都会遍历所有边,并尝试通过每条边来减少到达目标节点的距离。

  5. 结果输出:最后检查 minDist[n] 是否仍然为 Integer.MAX_VALUE,如果是,则表示不存在从起始节点到目标节点的路径;否则输出最短路径长度。

代码

import java.util.*;
public class Main {

    // Define an inner class Edge
    static class Edge {
        int from;
        int to;
        int val;
        public Edge(int from, int to, int val) {
            this.from = from;
            this.to = to;
            this.val = val;
        }
    }

    public static void main(String[] args) {
        // Input processing
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        List<Edge> edges = new ArrayList<>();

        for (int i = 0; i < m; i++) {
            int from = sc.nextInt();
            int to = sc.nextInt();
            int val = sc.nextInt();
            edges.add(new Edge(from, to, val));
        }

        // Represents the minimum distance from the current node to the original node
        int[] minDist = new int[n + 1];

        // Initialize the minDist array
        Arrays.fill(minDist, Integer.MAX_VALUE);
        minDist[1] = 0;

        // Starts the loop to relax all edges n - 1 times to update minDist array
        for (int i = 1; i < n; i++) {

            for (Edge edge : edges) {
                // Updates the minDist array
                if (minDist[edge.from] != Integer.MAX_VALUE && (minDist[edge.from] + edge.val) < minDist[edge.to]) {
                    minDist[edge.to] = minDist[edge.from] + edge.val;
                }
            }
        }

        // Outcome printing
        if (minDist[n] == Integer.MAX_VALUE) {
            System.out.println("unconnected");
        } else {
            System.out.println(minDist[n]);
        }
    }
}

易错点

代码假设起始节点总是 1,但在实际应用中,起始节点可能是任意一个节点。如果输入指定起始节点,需要相应修改代码

总结

算法真是一个坚持的过程

继续加油!

世界上只有想不通的人,没有走不通的路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2092860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode 未定义标识符 “uint16_t“C/C++(20) 但是可以顺利编译

这是没有指定编译器的原因 解决方法&#xff1a; 打开 或c_cpp_properties.json&#xff0c;添加编译器

★ 算法OJ题 ★ 力扣611 - 有效三角形的个数

Ciallo&#xff5e;(∠・ω< )⌒☆ ~ 今天&#xff0c;椎名日和将和大家一起做一道双指针算法题--有效三角形的个数~ 目录 一 题目 二 算法解析 三 编写算法 一 题目 二 算法解析 给三个数&#xff0c;判断是否能构成三角形的条件&#xff1a;两个较小的数相加大于…

机器学习数学公式推导之高斯分布

文章目录 1、介绍引入1.1 频率派的观点1.2 贝叶斯派的观点1.3 小结 2、数学基础2.1 二阶中心矩2.2 样本方差2.3 高斯分布2.3.1 一维情况 MLE2.3.2 多维情况 本文参考 B站UP: shuhuai008 跳转 &#x1f339;&#x1f339; 1、介绍引入 在统计学和概率论中&#xff0c; P ( x ∣ …

史上最全的MybatisPlus学习教程从入门到精通

一、MybatisPlus是什么 1.1 MyBatis-Plus简介 MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;它在MyBatis的基础上进行了增强&#xff0c;但并没有改变原有的MyBatis框架。MyBatis-Plus的主要目标是简化开发和提高开发效率。它提供了诸如分…

源码阅读-SpirngBoot Mybatis 自动配置

MybatisPlusAutoConfiguration ObjectProvider#getIfAvailable ObjectProvider为我们提供了拓展&#xff0c;我们可以自定义一些插件或者类型转换器&#xff0c;同时也可以定义一些Customizer用来配置SqlSessionFactoryBean,MybatisPlusProperties等。 通过源码我们可以看到最…

Redis从入门到入门(上)

1.Redis概述 文章目录 1.Redis概述1.1 什么是Redis1.2 Redis的应用场景 2.Linux下Redis的安装与使用2.1 Redis下载2.2 Redis的启动2.3 Redis配置2.4 连接Redis 1.1 什么是Redis Redis是用C语言开发的一个开源的高性能键值对&#xff08;key-value&#xff09;数据库&#xff0…

数学建模--K-Means聚类分析

目录 1.聚类分析步骤 1.1简单介绍 1.2两个概念 1.3几种距离 1.4更新质心 1.5终止条件 2.归一化处理 3.肘部法则 4.搭建K-Means分析模型 5.选择最佳K值 6.绘制3D图形 1.聚类分析步骤 1.1简单介绍 K-Means聚类分析是属于聚类分析的一种&#xff0c;这个数据机器学习的…

YOLOv8改进 | Neck篇 | YOLOv8引入Slim-Neck(超轻量)

1. Slim-Neck介绍 摘要:目标检测是计算机视觉中重要的下游任务。 对于车载边缘计算平台来说,巨大的模型很难达到实时检测的要求。 而且,由大量深度可分离卷积层构建的轻量级模型无法达到足够的精度。 我们引入了一种新的轻量级卷积技术 GSConv,以减轻模型重量但保持准确性。…

《软件工程导论》(第6版)第4章 形式化说明技术 复习笔记

第4章 形式化说明技术 一、概述 按照形式化的程度&#xff0c;可以把软件工程使用的方法划分成非形式化、半形式化和形式化3类。用自然语言描述需求规格说明&#xff0c;是典型的非形式化方法。用数据流图或实体联系图建立模型&#xff0c;是典型的半形式化方法。所谓形式化…

idea的springboot里面的resources是什么

在IDEA&#xff08;IntelliJ IDEA&#xff09;中的Spring Boot项目中&#xff0c;resources目录扮演着非常重要的角色。这个目录主要用于存放项目的非代码资源&#xff0c;包括但不限于配置文件、静态资源文件&#xff08;如图片、CSS、JavaScript等&#xff09;、模板文件&…

YOLO缺陷检测学习笔记(2)

YOLO缺陷检测学习笔记&#xff08;2&#xff09; 残差连接1. **YOLO 的残差连接结构**2. **YOLO 使用残差连接的目的**3. **YOLO 中的残差块**4. **YOLOv3 和 YOLOv4 的残差连接架构** YOLO网络架构概述1. 特征提取网络2. 预测头&#xff08;Detection Head&#xff09;3. 后处…

Android CCodec Codec2 (五)C2Param - Ⅲ

这一节我们来看看简单参数的定义方式 1、C2SimpleValueStruct Codec2框架提供了模板类C2SimpleValueStruct来帮助我们定义非灵活数组的简单参数。C2SimpleValueStruct的定义如下&#xff1a; template<typename T> struct C2SimpleValueStruct {T value; ///< simpl…

阿里 “通义灵码” 真的 “灵吗”,全保姆级实操

最近很多朋友&#xff0c;都在关注阿里公测的“通义灵码”&#xff0c;我索性也安装了&#xff0c;准备看看它真的有说的那么“灵吗”&#xff1f; 一、安装 官网&#xff1a;https://tongyi.aliyun.com/lingma/ 安装方式&#xff1a;https://tongyi.aliyun.com/lingma/downl…

Redis 集群:引领企业级 NoSQL 数据库新潮流

一 、关系型数据库和 NoSQL 数据库 在当今的数据库领域&#xff0c;关系型数据库和非关系型数据库都占据着重要的地位。 关系型数据库 关系型数据库是建立在关系模型基础上的数据库&#xff0c;它通过表与表之间的关系来存储和管理数据。 特点 数据结构清晰&#xff1a;以二…

“微服务革命”之后...

曾几何时&#xff0c;我记得我的手指疯狂地敲打键盘&#xff0c;与庞大而杂乱的代码库搏斗。那是巨石的时代&#xff0c;代码就像古老的城堡一样&#xff0c;由一块块石头砌成一个令人印象深刻的庞然大物。 几年过去了&#xff0c;时代变了。开发人员口中的流行语变成了“微服…

基于STM32校车安全监控系统的设计(论文+源码+实物)

1 方案设计 根据设计要求&#xff0c;本设计校车安全监控系统的设计以STM32F103单片机作为主控制器&#xff0c;通过MQ传感器实现异常气体的检测&#xff0c;当异常气体浓度异常时会通过继电器打开车窗进行通风&#xff0c;以保证舒适的环境&#xff0c;通过红外传感器用于监…

EXO:StandardNode _process_tensor

目录 EXO:StandardNode _process_tensor EXO:StandardNode _process_tensor 这段代码是在处理某种分片(sharding)逻辑时使用的,特别是在处理大型模型或数据处理任务时,这些任务被分割成多个较小的部分(即分片)来并行处理。这里,代码片段关注于根据特定的调试级别(DEBU…

大数据处理从零开始————1.Hadoop介绍

1. 大数据时代背景 1.1 大数据时代到来 在微信上&#xff0c;随手点的一个赞&#xff1b;在百度上&#xff0c;随手输入的搜素关键词&#xff1b;在健康记录应用上&#xff0c;每天所产生的微信步数这些都是数据。我们每人每天都在产生大量数据。人类近些年所产生的数据比过去…

【设计模式】创建型模式——简单工厂模式

文章目录 一、创建型模式1. 包含模式1.1 工厂模式1.2 建造者模式1.3 原型模式1.4 单例模式 二、工厂模式1. 概要1.1 意图1.2 主要解决问题1.3 何时使用1.4 如何解决1.5 关键代码1.6 使用场景1.7 优点1.8 缺点1.9 简单工厂实现 2. 简单工厂模式2.1 模式结构2.2 实例2.3 模式定义…

Charles激活

简介 Charles激活码计算 激活 Help -> Register Charles 添加 Registered Name 和计算出的 License key 点击 Register Java import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Random; import java.util.Scanner;/*** program: ZK* descriptio…