蓝桥杯第2357题——限高杆(多层图+dijkstra)

问题描述

某市有 𝑛 个路口, 有 𝑚 段道路连接这些路口, 组成了该市的公路系统。其 中一段道路两端一定连接两个不同的路口。道路中间不会穿过路口。

由于各种原因, 在一部分道路的中间设置了一些限高杆, 有限高杆的路段 货车无法通过。

在该市有两个重要的市场 𝐴 和 𝐵, 分别在路口 1 和 𝑛 附近, 货车从市场 𝐴 出发, 首先走到路口 1 , 然后经过公路系统走到路口 𝑛, 才能到达市场 𝐵 。两 个市场非常繁华, 每天有很多货车往返于两个市场之间。

市长发现, 由于限高杆很多, 导致货车可能需要绕行才能往返于市场之间, 这使得货车在公路系统中的行驶路程变长, 增加了对公路系统的损耗, 增加了 能源的消耗, 同时还增加了环境污染。

市长决定要将两段道路中的限高杆拆除, 使得市场 𝐴 和市场 𝐵 之间的路程变短。请问最多能减少多长的距离?

输入格式

输入的第一行包含两个整数 𝑛,𝑚 分别表示路口的数量和道路的段数。

接下来 𝑚m 行, 每行四个整数 𝑎,𝑏,𝑐,𝑑 表示路口 𝑎a 和路口 𝑏 之间有一段长 度为 𝑐 的道路。如果 𝑑 为 0 , 表示这段道路上没有限高杆; 如果 𝑑 为 1 , 表示 这段道路上有限高杆。两个路口之间可能有多段道路。

输入数据保证在不拆除限高杆的情况下, 货车能通过公路系统从路口 1 正常行驶到路口 𝑛 。

输出格式

输出一行,包含一个整数, 表示拆除两段逅路的限高杆后, 市场 𝐴 和市场 𝐵 之间的路程最大减少多长距离。

样例输入

5 7
1 2 1 0
2 3 2 1
1 3 9 0
5 3 8 0
4 3 5 1
4 3 9 0
4 5 4 0

样例输出

6

样例说明

只有两段道路有限高杆, 全部拆除后, 1 到 𝑛 的路程由原来的 17 变为了 11,减少了 6。

评测用例规模与约定

对于 30% 的评测样例, 2 ≤ 𝑛 ≤ 10, 1 ≤ 𝑚 ≤ 20, 1 ≤ 𝑐 ≤ 100 。

对于 50% 的评测样例, 2 ≤ 𝑛 ≤ 100,1 ≤ 𝑚 ≤ 1000,1 ≤ 𝑐 ≤ 1000。

对于 70% 的评测样例, 2 ≤ 𝑛 ≤ 1000, 1 ≤ 𝑚 ≤ 10000, 1 ≤ 𝑐 ≤ 10000。

对于所有评测样例, 2 ≤ 𝑛 ≤ 10000, 2 ≤ 𝑚 ≤ 100000, 1 ≤ 𝑐 ≤ 10000。

解题思路

这道题明确的说,我们考虑的是固定的起点和固定的终点,那么很容易想到单源最短路径dijkstra算法,这是一个bfs+优先队列的解题方法,若读者尚未了解建议先行学习。

这道题不一样的点在于,对于边是有不同的种类的,一种是没有限高架,一种是有限高架,市长想要撤销最多两个限高架,使得固定起点和终点的路径长度得到最大优化。

这里我们使用多层图+dijkstra算法来完成,建立一个三层图,单层内点与点之间的边就是没有限高架的边,而跨层的情况我们使用第二类有限高架的单向跨层边,根据这样的设计,从第一层的起点,到第三层的终点就是经过最多两个限高架的最短距离。

对于跨层边,跨层的单向边建立起来是两条,读者可能会感到困惑。举个例子,对于Ai表示第i层的点A,则有a1可以到b2(b2不可以到a1),b1可以到a2(a2不可以到b1)。所以应当明白,如果是双向边,则双向跨层边应当会有四条,而这里的两条则是单向跨层边。

基于上述设计,我们从第一层的起点到第三层的终点,就不会存在中途回层的问题。

最后,我们还要对不同层的同一个节点,即a1->a2、a2->a3、a1->a3的边权值置为0,因为有限高架的路径也可能非常不划算,这样设计就不必担心跨层必须要经过限高架的问题了,不经过限高架路段也可以免费跨层来到下层的结点。

import java.util.*;public class Main{static final long INF = (long)1e9;static int n, m;// 这里用HashMap代替了ArrayList<Node>,可以在log复杂度处理重边static ArrayList<HashMap<Integer, Long>> edges;public static void main(String[] args) {Scanner sc = new Scanner(System.in);n = sc.nextInt();m = sc.nextInt();sc.nextLine();edges = new ArrayList<>();for (int i = 0; i <= 3 * n; i++) {edges.add(new HashMap<>());}for (int i = 1; i <= m; i++) {String[] temp = sc.nextLine().split(" ");int u = Integer.parseInt(temp[0]);int v = Integer.parseInt(temp[1]);long w = Long.parseLong(temp[2]);int f = Integer.parseInt(temp[3]);if (f == 1) {link(u, v + n, w);link(v, u + n, w);link(u + n, v + 2 * n, w);link(v + n, u + 2 * n, w);} else {link(u, v, w);link(v, u, w);link(u + n, v + n, w);link(v + n, u + n, w);link(u + 2 * n, v + 2 * n, w);link(v + 2 * n, u + 2 * n, w);}}// 同一个节点免费跨层for (int i = 1; i <= n; i++) {link(i, i + n, 0);link(i + n, i + 2 * n, 0);link(i, i + 2 * n, 0);}long ans = dij();System.out.print(ans);}// 添加边,并处理重边,只保留最短的static void link(int u, int v, long w) {edges.get(u).put(v, Math.min(w, edges.get(u).getOrDefault(v, INF)));}static boolean[] visited;static long[] dist;static PriorityQueue<Node> qu;static long dij() {visited = new boolean[3 * n + 1];qu = new PriorityQueue<>(Comparator.comparing(node -> node.w));dist = new long[3 * n + 1];Arrays.fill(dist, INF);dist[1] = 0;qu.offer(new Node(1, 0));while (!qu.isEmpty()) {Node node = qu.poll();int u = node.id;long s = node.w;if (visited[u]) {continue;}visited[u] = true;for (java.util.Map.Entry<Integer, Long> entry : edges.get(u).entrySet()) {int v = entry.getKey();long w = entry.getValue();if (!visited[v]) {if (dist[v] > dist[node.id] + w) {dist[v] = dist[node.id] + w;qu.offer(new Node(v, dist[v]));}}}}System.out.println(Arrays.toString(dist));// dist[n]表示只在第一层走到终点,也就是不经过任何限高架路段的原始最短距离return dist[n] - dist[3 * n];}
}// 对于优先队列中的每一个节点
// 存储的是节点的编号,以及其到起点的距离
class Node {int id;long w;public Node(int id, long w) {super();this.id = id;this.w = w;}
}

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

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

相关文章

【微命令】git config如何配置全局的用户和邮箱?(--global user.name、user.email;git config --help)

虽然经常用&#xff0c;也经常忘记&#xff0c;特此记录。 命令 git config --global user.name "myname" git config --global user.email test163.com另外一种方式 help git config --help |grep email | grep name直接help查看

Git系列:git log 掌握版本控制的精髓

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【科普】ChatGPT-4o 是什么?和之前的ChatGPT4.0有什么区别,各有什么优劣势

文章目录 前言一、ChatGPT-4o 是什么&#xff1f;**主要特点和改进**&#xff1a; 二、ChatGPT-4o 和之前的ChatGPT4.0有什么区别&#xff0c;各有什么优劣势区别优势和劣势ChatGPT-4.0ChatGPT-4o 前言 5月13日&#xff0c;ChatGPT-4o发布&#xff0c;是人工智能的进一步发展&…

【leetcode面试经典150题】-27. 移除元素

88.合并两个有序数组 1 题目介绍1 个人解题思路1.1 解题代码1.2 思路解析 2、分析官方题解2.1 单侧双指针2.2 双侧双指针 1 题目介绍 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外…

Echarts结课之小杨总结版

Echarts结课之小杨总结版 前言基础回顾框架sale框架代码&#xff1a; user框架基础代码&#xff1a; inventory框架基础代码&#xff1a; total框架基础代码&#xff1a; 基础设置1.标题(Title)2.图例(Legend)实现 3.工具提示(Tooltip)实现 4.X轴(X Axis) 和 Y轴(Y Axis)5.数据…

「Qt Widget中文示例指南」如何实现一个快捷编辑器(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 快捷编辑器示例展示…

Leetcode 第 129 场双周赛题解

Leetcode 第 129 场双周赛题解 Leetcode 第 129 场双周赛题解题目1&#xff1a;3127. 构造相同颜色的正方形思路代码复杂度分析 题目2&#xff1a;3128. 直角三角形思路代码复杂度分析 题目3&#xff1a;3129. 找出所有稳定的二进制数组 I思路代码复杂度分析 题目4&#xff1a;…

电子邮箱是什么?怎么申请一个电子邮箱?

电子邮箱是我们沟通的工具&#xff0c;细分为免费版电子邮箱和付费版电子邮箱。怎么申请一个属于自己的电子邮箱&#xff1f;今天小编就分享一下电子邮箱注册教程&#xff0c;手把手教您注册一个电子邮箱。 一、电子邮箱的定义 电子邮箱&#xff0c;简称邮箱&#xff0c;是一…

BGP路由优选

1.BGP路由优选规则 上述规则依序排列&#xff0c;BGP进行路由优选时&#xff0c;从第一条规则开始执行&#xff0c;如果根据第一条规则无法作出判断&#xff0c;例如路由的Preferred-Value属性值相同&#xff0c;则继续执行下一条规则&#xff0c;如果根据当前的规则&#xff0…

如何快速打开多个网页?

在平常的工作当中&#xff0c; 如果每天都需固定打开几个网站&#xff0c;可以通过创建一个批处理&#xff0c;一键打开需要的所有网站。 使用方法&#xff1a; 在桌面新建一个txt文本&#xff0c;按照以下格式输入代码&#xff0c;并将需要打开网站的地址输入进去。 ​ ec…

JavaScript异步编程——11-异常处理方案【万字长文,感谢支持】

异常处理方案 在JS开发中&#xff0c;处理异常包括两步&#xff1a;先抛出异常&#xff0c;然后捕获异常。 为什么要做异常处理 异常处理非常重要&#xff0c;至少有以下几个原因&#xff1a; 防止程序报错甚至停止运行&#xff1a;当代码执行过程中发生错误或异常时&#x…

虚拟化技术 在vCenter Server创建数中心、添加主机

一、实验内容 1.安装Flash 2.在vCenter Server创建数中心、添加主机 二、实验主要仪器设备及器材 1.安装有64位Windows操作系统的台式电脑或笔记本电脑&#xff0c;建议4C8G或以上配置 2.在Windows Server 2008 R2已安装vCenter Server 3.Adobe Flash Player 12.0.0.70.e…

算法-卡尔曼滤波之卡尔曼滤波的第一个方程:状态更新方程

通过一个例子来引出卡尔曼滤波的状态更新方程&#xff1b; 这里系统状态是金条的重量&#xff1b; 为了估计系统的状态&#xff0c;我们可以多次测量金条的重量&#xff0c;然后求平均值&#xff1b; 其中估计值是所有测量值的平均值&#xff1b; 由于我们使用的是静态模型&am…

第十六节:图 (20节)

一 图的概念 1&#xff09;由点的集合和边的集合构成 2&#xff09;虽然存在有向图和无向图的概念&#xff0c;但实际上都可以用有向图来表达 3&#xff09;边上可能带有权值 二 图结构的表达 1&#xff09;邻接表法 2&#xff09;邻接矩阵法 3&#xff09;除此之外还有其他众多…

Halcon与深度学习框架结合进行图像分析

Halcon 是一款强大的机器视觉软件&#xff0c;而深度学习框架如 TensorFlow 或 PyTorch 在图像识别和分类任务中表现出色。结合两者的优势&#xff0c;可以实现复杂的图像分析任务。Halcon 负责图像预处理和特征提取&#xff0c;而深度学习框架则利用这些特征进行高级分析和识别…

【完整过程】Windows下记录PadleOCR训练自己的ocr模型

一、前期准备 1、代码 参考的博主使用的是2.6版本的 博主的paddleocr代码 下面这个是官方的&#xff0c;可能已经更新了&#xff08;我用的是官网当前最新版&#xff09; paddleocr的源代码 注意&#xff1a;最好把上面两个代码都下载下来&#xff0c;后面都会用到 参考博…

先有JVM还是先有垃圾回收器?

是先有垃圾回收器再有JVM呢&#xff0c;还是先有JVM再有垃圾回收器呢&#xff1f;或者是先有垃圾回收再有JVM呢&#xff1f;历史上还真是垃圾回收更早面世&#xff0c;垃圾回收最早起源于1960年诞生的LISP语言&#xff0c;Java只是支持垃圾回收的其中一种。下面我们就来刨析刨析…

免费思维13招之十一:利润型思维

免费思维13招之十一:利润型思维 免费思维的另一大战略思维——利润型思维。 什么是利润型思维呢?就是用后期的利润来支付现在的成本。也就是“花未来的钱,办现在的事”。 我们在销售自己的产品时候,最容易犯的一个件事,就是降价,我们先来看一个案例: 前几年,有一个卖…

React获取form表单值的N种方式

Ref模式&#xff08;非受控模式&#xff09; 非钩子模式 1.createRef()方式 js: userNameElcreateRef() <input type"text" name"userName" ref{this.userNameEl} /> 获取值的方式&#xff1a; this.userNameEl.current.value2.refs(废弃) js: con…

自动化图像识别:提高效率和准确性的新途径

自动化图像识别是人工智能领域中的一项关键技术&#xff0c;它通过算法自动解析图像内容&#xff0c;为各种应用提供准确的信息。随着技术的不断发展&#xff0c;自动化图像识别在提高效率和准确性方面展现出新的途径。 一、深度学习技术的应用 深度学习是自动化图像识别领域…