代码随想录Day74(图论Part10)

94. 城市间货物运输| (Bellman_ford队列优化版 / SPFA)

题目:94. 城市间货物运输 I (kamacoder.com)

思路:

Bellman_ford 算法 每次都是对所有边进行松弛,其实是多做了一些无用功。

只需要对 上一次松弛的时候更新过的节点作为出发节点所连接的边 进行松弛就够了

因此,关键在于记录上次松弛更新过的节点,用队列来记录。

答案
import java.util.*;

class Edge {
    int to;  // 链接的节点
    int val; // 边的权重

    Edge(int t, int w) {
        to = t;
        val = w;
    }
}

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>> graph = new ArrayList<>();
        for (int i = 0; i <= n; i++) {
            graph.add(new ArrayList<>());
        }

        // 将所有边保存起来
        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            // p1 指向 p2,权值为 val
            graph.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);
        minDist[start] = 0;

        Queue<Integer> queue = new LinkedList<>();
        queue.offer(start); // 队列里放入起点

        while (!queue.isEmpty()) {
            int node = queue.poll();

            for (Edge edge : graph.get(node)) {
                int from = node;
                int to = edge.to;
                int value = edge.val;
                if (minDist[to] > minDist[from] + value) { // 开始松弛
                    minDist[to] = minDist[from] + value;
                    queue.offer(to);
                }
            }
        }

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

        scanner.close();
    }
}
小结

邻接表存储,方便找到 上一次松弛时,更新过的节点作为出发节点所连接的边

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

 使用LinkedList实现Queue,不断从中 poll 出节点node,操作 node 的 edge,将 node.to 加入到队列中

Queue<Integer> queue = new LinkedList<>();
queue.offer(start); // 队列里放入起点

while (!queue.isEmpty()) {
    int node = queue.poll();

    for (Edge edge : graph.get(node)) {
        int from = node;
        int to = edge.to;
        int value = edge.val;
        if (minDist[to] > minDist[from] + value) { // 开始松弛
            minDist[to] = minDist[from] + value;
            queue.offer(to);
        }
    }
}

95.城市间货物运输|| (Bellman_ford判断负权回路)

题目:95. 城市间货物运输 II (kamacoder.com)

思路:出现负权回路,按照之前的思路,会一直循环回路,使得成本不断减小,因此核心思路是,在Bellman_ford标准版基础上,再松弛一次,看结果是否变化

SPFA(Bellman_ford优化版),则是看节点加入队列次数是否超过n-1次

答案
import java.util.*;

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

        int n = scanner.nextInt();  // 顶点数
        int m = scanner.nextInt();  // 边数

        List<int[]> edges = new ArrayList<>();

        // 将所有边保存起来
        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            edges.add(new int[]{p1, p2, val});
        }

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

        int[] minDist = new int[n + 1];
        Arrays.fill(minDist, Integer.MAX_VALUE);
        minDist[start] = 0;
        boolean flag = false;

        // 对所有边松弛 n 次,最后一次判断负权回路
        for (int i = 1; i <= n; i++) {
            for (int[] edge : edges) {
                int from = edge[0];
                int to = edge[1];
                int price = edge[2];
                if (i < n) {
                    if (minDist[from] != Integer.MAX_VALUE && minDist[to] > minDist[from] + price) {
                        minDist[to] = minDist[from] + price;
                    }
                } else { // 多加一次松弛判断负权回路
                    if (minDist[from] != Integer.MAX_VALUE && minDist[to] > minDist[from] + price) {
                        flag = true;
                    }
                }
            }
        }

        if (flag) {
            System.out.println("circle");
        } else if (minDist[end] == Integer.MAX_VALUE) {
            System.out.println("unconnected");
        } else {
            System.out.println(minDist[end]);
        }

        scanner.close();
    }
}

95.城市间货物运输|||(Bellman_ford单源有限最短路径)

题目:96. 城市间货物运输 III (kamacoder.com)

思路:关键是在于,每次松弛要基于上一次松弛的结果

答案
import java.util.*;

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

        int n = scanner.nextInt();  // 顶点数
        int m = scanner.nextInt();  // 边数

        List<int[]> edges = new ArrayList<>();

        // 将所有边保存起来
        for (int i = 0; i < m; i++) {
            int p1 = scanner.nextInt();
            int p2 = scanner.nextInt();
            int val = scanner.nextInt();
            edges.add(new int[]{p1, p2, val});
        }

        int src = scanner.nextInt();  // 起点
        int dst = scanner.nextInt();  // 终点
        int k = scanner.nextInt();    // 最大边数

        int[] minDist = new int[n + 1];
        Arrays.fill(minDist, Integer.MAX_VALUE);
        minDist[src] = 0;

        int[] minDistCopy = new int[n + 1];

        // 进行 k+1 次松弛操作
        for (int i = 1; i <= k + 1; i++) {
            System.arraycopy(minDist, 0, minDistCopy, 0, minDist.length); // 获取上一次计算的结果
            for (int[] edge : edges) {
                int from = edge[0];
                int to = edge[1];
                int price = edge[2];
                // 注意使用 minDistCopy 来计算 minDist
                if (minDistCopy[from] != Integer.MAX_VALUE && minDist[to] > minDistCopy[from] + price) {
                    minDist[to] = minDistCopy[from] + price;
                }
            }
        }

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

        scanner.close();
    }
}
小结

更新用的是minDist,判断用的是minDistCopy

if (minDistCopy[from] != Integer.MAX_VALUE && minDist[to] > minDistCopy[from] + price) {
    minDist[to] = minDistCopy[from] + price;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot中使用SpringEvent组件

Spring的事件机制是基于观察者模式的实现&#xff0c;主要由以下三个部分组成&#xff1a; 事件&#xff08;Event&#xff09;&#xff1a;事件是应用中发生的重要事情&#xff0c;通常是一个继承自ApplicationEvent的类。 事件发布器&#xff08;Publisher&#xff09;&…

ubuntu使用官方deb文件安装指定版本cuda失败,总是装成最新版

之前安装过最新版的cuda&#xff0c;之后想换用旧版&#xff0c;但是按照官网的说明&#xff0c;sudo apt-get -y install cuda后总是装成最新版的。 解决方法&#xff1a; 最后一步使用sudo apt-get -y install cuda-x-x&#xff0c;直接指定你要安装的cuda的版本号。

python作业一

1. #A. num int(input("请输入要打印的层数:")) for n in range(1, num1):s ""for i in range(1, n1):s f"{i}" " "print(s)#B. num int(input("请输入要打印的层数:")) for i in range(num1, 0, -1):s" "f…

springcloud+vue项目,controller层接口返回json数据,前端可以接收到数据,但浏览器“F12-->网络-->响应“显示为空的问题处理

1.显示为空的场景 SharetekR(access_tokeneyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJQQzoxODA1ODA4ODc1MjUwMTIyNzUyIiwicm5TdHIiOiJrZEoxV05CV3NBSUdYb05TbktSU3kzOGNuSnk3c3FRTSIsInVzZXJJZCI6MTgwNTgwODg3NTI1MDEyMjc1MiwidXNlck5h…

分布式数据库HBase:从零开始了解列式存储

在接触过大量的传统关系型数据库后你可能会有一些新的问题: 无法整理成表格的海量数据该如何储存? 在数据非常稀疏的情况下也必须将数据存储成关系型数据库吗? 除了关系型数据库我们是否还有别的选择以应对Web2.0时代的海量数据? 如果你也曾经想到过这些问题, 那么HBase将是…

25届最近5年华北电力大学自动化考研院校分析

华北电力大学&#xff08;北京保定&#xff09; 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、初试大纲复试大纲 七、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指…

【C语言】刷题笔记 Day2

【笔记】 【1】局部变量不初始化&#xff0c;默认放的随机值。 1 int n0; 2 scanf("%d",&n); //13.141 【2】这里虽然输入的是一个浮点数&#xff0c;但是只取整数部分。 【3】3.156e7 表示的是3.156*10的7次方。 【4】多组输入&#xff0c;保存和不保存…

关于Wav2Lip配置实现

模型介绍 Wav2Lip是一种先进的深度学习模型&#xff0c;旨在将音频波形直接转换为面部动画&#xff0c;尤其关注于唇部动作的生成与同步。这一技术的核心在于其能够利用输入的语音信号&#xff0c;生成与之高度匹配的嘴唇动作&#xff0c;从而实现逼真的语音驱动数字人物动画效…

docker初始化运行mysql容器时自动导入数据库存储过程问题

问题&#xff1a;用navicat导出的数据库脚本&#xff0c;在docker初始化运行mysql容器时&#xff0c;导入到存储过程时出错。 ERROR 1064 (42000) at line 2452: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for t…

DataWhale-吃瓜教程学习笔记 (六)

学习视频**&#xff1a;第4章-决策树_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第五章 5.1&#xff1b;5.2&#xff1b;5.3 文章目录 MP 神经元- 感知机模型 &#xff08;分类模型&#xff09;-- 损失函数定义--- 感知机学习算法 - 随机梯度下降法 - 神经网络需要解决的问…

2024年显著性检测部分论文及代码汇总(3)

ICML Size-invariance Matters: Rethinking Metrics and Losses for Imbalanced Multi-object Salient Object Detection code Abstacrt&#xff1a;本文探讨了显著性检测中评价指标的尺寸不变性&#xff0c;尤其是当图像中存在多个大小不同的目标时。作者观察到&#xff0c;…

解决Python爬虫开发中的数据输出问题:确保正确生成CSV文件

引言 在大数据时代&#xff0c;爬虫技术成为获取和分析网络数据的重要工具。然而&#xff0c;许多开发者在使用Python编写爬虫时&#xff0c;常常遇到数据输出问题&#xff0c;尤其是在生成CSV文件时出错。本文将详细介绍如何解决这些问题&#xff0c;并提供使用代理IP和多线程…

开始尝试从0写一个项目--前端(一)

基础项目构建 创建VUE初始工程 确保自己下载了node.js和npm node -v //查看node.js的版本 npm -v //查看npm的版本 npm i vue/cli -g //安装VUE CLI 创建 以管理员身份运行 输入&#xff1a;vue ui 就会进入 点击创建 自定义项目名字&#xff0c;选择npm管理 结…

C++ 智能指针内存泄漏问题

shared_ptr相互嵌套导致循环引用 代码示例 #include <iostream> #include <memory> using namespace std;class B;class A { public:std::shared_ptr<B> b_ptr;~A() { std::cout << "A destroyed\n"; } };class B { public:std::shared_pt…

【前端项目笔记】8 订单管理

订单管理 效果展示&#xff1a; 在开发功能之前先创建分支order cls 清屏 git branch 查看所有分支&#xff08;*代表当前分支&#xff09; git checkout -b order 新建分支order git push -u origin order 将本地的当前分支提交到云端仓库origin中命名为order 通过路由方式…

014-GeoGebra基础篇-快速解决滑动条的角度无法输入问题

有客户反馈&#xff0c;他的Geogebra一直有个bug&#xff0c;那就是输入角度最大值时总不按照他设定的展示&#xff0c;快被气炸了~ 目录 一、问题复现&#xff08;1&#xff09;插入一个滑动条&#xff08;2&#xff09;选择Angle&#xff08;3&#xff09;输入90&#xff0c;…

|从零搭建网络| VisionTransformer网络详解及搭建

&#x1f31c;|从零搭建网络| VisionTransformer系列网络详解及搭建&#x1f31b; 文章目录 &#x1f31c;|从零搭建网络| VisionTransformer系列网络详解及搭建&#x1f31b;&#x1f31c; 前言 &#x1f31b;&#x1f31c; VIT模型详解 &#x1f31b;&#x1f31c; VIT模型架…

Buuctf之不一样的flag(迷宫题)

首先&#xff0c;进行查壳无壳&#xff0c;32bit&#xff0c;丢进ida32中进行反编译进入main函数&#xff0c;对其进行分析&#xff0c;可以在一旁打上注释&#xff0c;这边最关键的一个点就是&#xff0c;需要联想到这是一个迷宫题&#xff0c;很小的迷宫题&#xff0c;迷宫就…

Kindling-OriginX 在快手 Staging 环境的异常诊断效果分享

业务可用性问题的快速诊断&#xff0c;历来是行业互联网公司面临的重大挑战&#xff0c;快手也不外如是。Kindling-OriginX的体系化设计理念快速打动了我们的工程师。快手随即开始了内部真实业务的验证落地&#xff1b;落地过程中&#xff0c;Kindling-OriginX能高效覆盖大部分…

classin视频下载提取为mp4教程

最近在上classin网课&#xff0c;无奈网课视频要过期了&#xff0c;所以想保存下来&#xff01; 下面介绍提取的教程 我们可以绕过最开始的握手&#xff0c;就是先播放了一段时间后&#xff0c;再打开抓包&#xff0c;回到Classin播放后&#xff0c;就可以获得网课链接了 直接打…