2024寒假集训营第四场 I回头 -- 题解 (带路径修改的Dijkstra)

目录

回头:

        题目大意:

        思路解析:

        代码实现:


回头:

        题目大意:

                给你一个n个点m条边的带权有向图,你现在需要从第一个点走到第n个点,求最短路径,当无解时输出-1. 值得注意的是你拥有一个可以无限使用的技能,如果你现在 在x结点前往y结点,你可以将y的任意一条出现永久修改为x->y的边(权值和之前保持一样)。

        思路解析:

                那我们可以注意到如果我们最终答案包含x->y这个值我们才需要将y的某一条出边修改为x->y,修改之后y就不能再通过这条边了。那如果我们在x->y的过程中就决定修改那条边的话,我们需要维护一个我们前往的y结点信息,和y结点哪个路径无法使用了,这样维护的信息开销太大,变为n^3,不可接受。

        但是如果我们在x结点只决定他需不需要当前x->y这个路径,那么就变为了dp[n][2]可以接受,但是如果我们不要的时候就直接加上当前这个路径权值,那我们之后还要删除,需要维护一个要删除的信息,这个是没有必要的,我们直接不加这个值,在下一次进行补充。(我们只需要维护一个欠费的信息即现在还有一条边的权值没有加上去)最多只能欠一次(补充之后,才能继续欠费)。

        在x欠费的情况下,假如 x->y, y可以到其余k个结点, (y到这k个结点的路径权值排序为 s0 s1 .... sk) 当我们选择s0这个路径前往下一个结点时,我们应当通过s1的值来进行补充,其余情况下我们应当使用s0的值进行补充。 (所以我们在维护这个有向图时,我们应当对整个路径权值进行排序)。

        代码实现:

                

import java.io.*;
import java.util.*;public class Main {static Vector<Node> g[];static long inf = (long) 1e18;public static void main(String[] args) throws IOException {int n = input.nextInt();int m = input.nextInt();g = new Vector[n+1];for (int i = 0; i < n + 1; i++) {g[i] = new Vector<>();}for (int i = 0; i < m; i++) {int x = input.nextInt();int y = input.nextInt();int val = input.nextInt();g[x].add(new Node(y, val));}long[][] dp = new long[n+1][2];for (int i = 0; i < n + 1; i++) {Arrays.fill(dp[i], inf);}dp[1][0] = 0;dp[1][1] = inf;for (int i = 1; i <= n; i++) {g[i].sort(new Comparator<Node>() {@Overridepublic int compare(Node o1, Node o2) {if (o1.val != o2.val) return o1.val - o2.val;else return o1.x - o2.x;}});}PriorityQueue<Pa> pas = new PriorityQueue<>(new Comparator<Pa>() {@Overridepublic int compare(Pa o1, Pa o2) {if (o1.val != o2.val){if (o1.val > o2.val) return 1;else return -1;}else if (o1.x != o2.x) return o1.x - o2.x;else return o1.st - o2.st;}});// 0 代表每欠费 1代表欠费pas.add(new Pa(1, 0, 0));while (!pas.isEmpty()){Pa cur = pas.poll();if (dp[cur.x][cur.st] < cur.val) continue;if (cur.st == 0){for (int i = 0; i < g[cur.x].size(); i++) {Node ne = g[cur.x].get(i);int y = ne.x;int val = ne.val;if (dp[cur.x][cur.st] + val < dp[y][0]){dp[y][0] = dp[cur.x][cur.st] + val;pas.add(new Pa(y, dp[y][0], 0));}if (dp[cur.x][cur.st] < dp[y][1]){dp[y][1] = dp[cur.x][cur.st];pas.add(new Pa(y, dp[y][1], 1));}}}else {for (int i = 0; i < g[cur.x].size(); i++) {Node ne = g[cur.x].get(i);int y = ne.x;int val = ne.val;if (i == 0 && i + 1 < g[cur.x].size()){if (dp[cur.x][cur.st] + val + g[cur.x].get(1).val < dp[y][0]){dp[y][0] = dp[cur.x][cur.st] + val + g[cur.x].get(1).val;pas.add(new Pa(y, dp[y][0], 0));}if (dp[cur.x][cur.st] + g[cur.x].get(1).val < dp[y][1]){dp[y][1] = dp[cur.x][cur.st] + g[cur.x].get(1).val;pas.add(new Pa(y, dp[y][1], 1));}}else if (i > 0){if (dp[cur.x][cur.st] + val + g[cur.x].get(0).val < dp[y][0]){dp[y][0] = dp[cur.x][cur.st] + val + g[cur.x].get(0).val;pas.add(new Pa(y, dp[y][0], 0));}if (dp[cur.x][cur.st] + g[cur.x].get(0).val < dp[y][1]){dp[y][1] = dp[cur.x][cur.st] + g[cur.x].get(0).val;pas.add(new Pa(y, dp[y][1], 1));}}}}}long ans = dp[n][0];if (g[n].size() >= 1){ans = Math.min(ans, dp[n][1] + g[n].get(0).val);}if (ans >= inf) out.println(-1);else out.println(ans);out.flush();out.close();br.close();}public static class Pa{int x;long val;int st;public Pa(int x, long val, int st) {this.x = x;this.val = val;this.st = st;}}public static class Node{int x;int val;public Node(int x, int val) {this.x = x;this.val = val;}}static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));static Input input = new Input(System.in);static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static class Input {public BufferedReader reader;public StringTokenizer tokenizer;public Input(InputStream stream) {reader = new BufferedReader(new InputStreamReader(stream), 32768);tokenizer = null;}public String next() {while (tokenizer == null || !tokenizer.hasMoreTokens()) {try {tokenizer = new StringTokenizer(reader.readLine());} catch (IOException e) {throw new RuntimeException(e);}}return tokenizer.nextToken();}public int nextInt() {return Integer.parseInt(next());}}
}

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

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

相关文章

CRF算法(Conditional Random Fields)揭秘

CRF基本介绍 在机器学习中&#xff0c;建模线性序列结构的方法&#xff0c;除了HMM算法&#xff0c;另一个重要的模型就是CRF。HMM为了降低模型复杂性&#xff0c;对观测变量做了独立假设(即隐状态之间有相关性&#xff0c;而观测变量之间没有相关性)&#xff0c;这在某种程度…

单机取证-信息安全管理与评估-2022年国赛真题-环境+wp

🍬 博主介绍 博主介绍:大家好,我是 Mikey ,很高兴认识大家~ 主攻:【应急响应】 【python】 【数字取证】【单机取证】【流量分析】【MISC】 🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步 作者水平有限,欢迎各…

HuggingFists系统功能介绍(2)--数据源账号

数据源 再次&#xff0c;我们进入“数据源”管理模块。该模块用于管理我们在进行数据处理或分析时所需要的所有数据源。在定义任何的数据流程读写工作之前&#xff0c;必须先通过数据源管理模块创建出对应的数据源。数据源可以是我们需要进行数据处理时&#xff0c;原始数据所在…

2024年软件测试岗位-面试

第一部分&#xff1a; 1、自我介绍&#xff1a;简历写到的快速描述&#xff0c;学校、学历、工作经验等&#xff08;注意&#xff1a;不要过度优化简历&#xff0c;你不写别人可能会问&#xff0c;但你写了别人一定会问&#xff01;&#xff09; 第二部分&#xff1a; 1、功能测…

uniapp上传文件到腾讯云

官方API地址 javaScript_SDK 下载cos npm i cos-js-sdk-v5 --save 生成签名 获取secretId和secretKey let cos new COS({SecretId: *******************************,SecretKey: ******************************,}) 参考文章&#xff1a;腾讯云如何获取secretId和secret…

【GB28181】从一个开源平台入门到实践系列文章汇总(持续更新)

前言 本文是GB28181从一个开源平台入门到实践系列文章专栏导航帖&#xff08;持续更新&#xff09; 建议大家在阅读专栏文章时&#xff0c;使用本导航进行阅读&#xff0c;读起来更有条例 专栏介绍&#xff1a;根据自己的项目实践&#xff0c;系统的总结了GB28181从了解&#…

C++中的左值和右值

目录 一. 左值和右值的概念 1. 左值 1.1 可修改的的左值 1.2 不可修改的左值 右值 二. 左值引用和右值引用 1. 左值引用 2. 右值引用 主要用途 1. 移动语义 2. 完美转发 2.1 引用折叠 2.2 std::forward 一. 左值和右值的概念 什么是左值和右值 1. 左值 左值是一个表示…

Linux内核源码安装

文章目录 前言查看内核源码包安装内核源码编译内核源码最后 前言 我是醉墨居士&#xff0c;我们安装一下Linux内核源码&#xff0c;方便我们学习Linux内核 也方便我们进行eBPF开发时查看Linux内核的一些信息 查看内核源码包 apt-cache search linux-source安装内核源码 因为…

拼接 URL(C 语言)【字符串处理】

题目来自于博主算法大师的专栏&#xff1a;最新华为OD机试C卷AB卷OJ&#xff08;CJavaJSPy&#xff09; https://blog.csdn.net/banxia_frontend/category_12225173.html 题目 给定一个 url 前缀和 url 后缀 通过,分割 需要将其连接为一个完整的 url 如果前缀结尾和后缀开头都…

Jetson Xavier NX配置Tensorrt路径

路径 include:/usr/include/aarch64-linux-gnu lib: /usr/lib/aarch64-linux-gnu tensorrt:/usr/src/tensorrt

【vue3语法】开发使用创建项目等

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、vue3创建vue3v2函数式、v3组合式api响应式方法ref、reactive计算属性conputed监听属性wacthvue3 选项式生命周期父子通信父传子defineProps编译宏 子传父de…

互联网加竞赛 机器视觉opencv答题卡识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 答题卡识别系统 - opencv python 图像识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分…

精读《源码学习》

1. 引言 javascript-knowledge-reading-source-code 这篇文章介绍了阅读源码的重要性&#xff0c;精读系列也已有八期源码系列文章&#xff0c;分别是&#xff1a; 精读《Immer.js》源码精读《sqorn 源码》精读《Epitath 源码 - renderProps 新用法》精读《Htm - Hyperscript…

并查集例题(食物链)C++(Acwing)

代码&#xff1a; #include <iostream>using namespace std;const int N 50010;int n, m; int p[N], d[N];int find(int x) {if(p[x] ! x){int t find(p[x]);d[x] d[p[x]];p[x] t;}return p[x]; }int main() {scanf("%d%d", &n, &m);for(int i 1…

阿里大文娱前端一面

引言 我目前本科大四&#xff0c;正在春招找前端&#xff0c;有大厂内推的友友可以聊一聊&#xff0c;球球给孩子的机会吧。 我整理了一份10w字的前端技术文档&#xff1a;https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink&#xff0c;对…

【蓝桥杯入门记录】静态数码管例程

目录 一、补充 &#xff08;code&#xff09; 二、例程 &#xff08;1&#xff09;例程1&#xff1a;数码管显示某一位&#xff08;某一杠&#xff09;。以点亮8段数码管最上面的横杠为例。 &#xff08;2&#xff09;例程2&#xff1a;数码管的8个段依次点亮&#xff08;其他…

linux前端部署

安装jdk 配置环境变量 刷新配置文件 source profile source /etc/profile tomcat 解压文件 进去文件启动tomcat 开放tomcat的端口号 访问 curl localhsot:8080 改配置文件 改IP,改数据库名字&#xff0c;密码&#xff0c; 安装数据库 将war包拖进去 访问http:…

C++递归

角谷猜想 #include<bits/stdc.h> using namespace std; int n,sum0; void f(int); int main() {cin>>n;f(n);cout<<sum;return 0; } void f(int n){if(n1) return;if(n%20) nn/2;if(n%21) nn*31;sum; } 求两个数M和N的最大公约数

【Python笔记-设计模式】代理模式

一、说明 代理模式是一种结构型设计模式&#xff0c;提供对象的替代品或其占位符。代理控制着对于原对象的访问&#xff0c;并允许在将请求提交给对象前后进行一些处理。 (一) 解决问题 控制对对象的访问&#xff0c;或在访问对象前增加额外的功能或控制访问 (二) 使用场景…

[c++] public, private, protected, friend

权限管理是 c 的一大特点&#xff0c;面向对象语言封装的特性也给权限管理带了了方便。c 中的权限主要有 3 种&#xff1a;public&#xff0c;private&#xff0c;protected。类中的函数和属性默认是 private 的&#xff0c;类的继承关系默认也是 private 的。 public&#xf…