CSP-J2023T4 旅游巴士(同余最短路)

news2024/11/5 16:38:06

题目链接:https://www.luogu.com.cn/problem/P9751

题意:给定 n 个点, m 条单向边,一个时间间隔 k 。有这样一些限制条件:

1)1号点是入口, n 号点是出口;

2)经过一条边的时间花费是1;

3)进入1号点和离开 n 号点的时刻都必须是 k 的整数倍(包括0),抵达其他点没有此限制;

4)每条边有开放时间 a_i ,在 a_i 时刻之前无法通过这条边;

5)不可以在任何一条边上或者点上停留,一旦从入口1号点进入后,就不能停下地走向 n 号点。

问从 n 号点离开的最早时刻是什么时候。如果不存在满足所有条件的旅行方案,输出-1。

数据范围: 2<=n<=10^4 , 2<=m<=2\times 10^4 , 1<=k<=100 , 0<=a_i<=10^6 。

样例模拟

整体思路

在不考虑有出发离开和道路开放的时间限制的情况下,这是一个求解单源最短路的图论题。求解单源最短路的算法普遍用的较多的有两种:

dijastra

spfa

但是需要注意到,在一个可行解的方案中,如果要保证离开n号点的时刻是k的整数倍,则倒数第二个节点抵达的时刻必须是模 k 等于 k-1 ,倒数第三个节点抵达的时刻必须是模 k 等于 k-2 …

所以要对图上每个节点做一个分层处理,按照抵达的时刻对 k 取模的结果分为 k 层,拆分成 k 个状态。

因本题没有负边权,所以选择哪种做法都可以,这里我们用是spfa算法来求解。

算法细节考虑

1)如何分层处理呢?

朴素最短路做法中的 dis[u] 变量用于存储抵达到点 u 时的最短路径,这里我们对该变量做分层处理,用 dis[u][i]=t 表示抵达点 u 时的最少花费时间为 t ,并且满足 t% k=i 。

那么到达1号点的合法状态只有 dis[1][0] ,离开 n 号点的合法状态只有 dis[n][0] 。

另外记录点是否已经被访问过的状态数组 st[u] ,也同样要这样分层处理,裂变为 st[u][i] ,我们在宽搜队列中也不能仅仅保存点的编号,同时也要保存点的状态:

q.push(pair<int,int>{u, i});

2)如何处理边上有开放时间的限制呢?

从点 u 转移至点 v 时,需要判断当前边是否开放,不妨设此时到达点 u 的时间为 t ,那么存在以下两种情况:

a) t>=a_i ,此时抵达时间已经晚于开放时间了,所以可以直接通过,那么抵达点 v 的时刻计算方式为 dis[v][j]=t+1,j=(t+1)%k ;

b) t<a_i ,此时抵达时间早于开放时间,可以假定往后延迟 k 的整数倍的时间进入1号点,那么该方案状态下保存的路径依旧合法,只是路径上所有遍历过的点的抵达时间往后延迟 k 的整数倍(但实际上我们并不会去修改所有遍历过的点的 dis 的值,因为它们可以用来更新其他不用延迟的后继点),这样就可以保证抵达时间晚于开放时间了, dis[v][j]=t+\lceil (a_i-t)/k\rceil\times k+1,j=(t+\lceil (a_i-t)/k\rceil\times k+1)%k 。

至此,需要考虑的细节已梳理完成。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 10005; // 点数
const int M = 20005; // 边数 
const int K = 105;

int n, m, k;
int h[N], e[M], w[M], ne[M], idx;
 
void add(int u, int v, int a) {
	e[idx] = v, w[idx] = a, ne[idx] = h[u], h[u] = idx++;
}

// dis[v][i]代表抵达v点的最小花费时间为t,且t%k=i
// 那么起始状态必须是dis[1][0],终结状态必须是dis[n][0]
// 如果t>=ai,那么dis[v][j]=t+1,j=(t+1)%k
// 如果t<ai,那么可以往后延长k的整数倍时间,new_t=dis[v][j]=t+向上取整[(ai-t)/k]*k+1,j=new_t%k
int dis[N][K]; 
bool st[N][K];
// 有解返回最短路解,无解返回-1 
int spfa() {
	queue<PII> q;
	memset(dis, 0x3f, sizeof dis);
	dis[1][0] = 0, st[1][0] = true;
	q.push({1, 0});
	while(q.size()) {
		PII p = q.front(); q.pop();
		int u = p.first, i = p.second;
		st[u][i] = false;
		for (int x = h[u]; x != -1; x = ne[x]) {
			int v = e[x], a = w[x];
			int t = dis[u][i];
			if (t < a) t += (a-t+k-1)/k * k;
			int j = (t+1) % k;
			if (dis[v][j] > t+1) {
				dis[v][j] = t+1;
				if (!st[v][j]) {
					st[v][j] = true;
					q.push({v, j});
				}
			}
		}
	}
	if (dis[n][0] == 0x3f3f3f3f)
		return -1;
	return dis[n][0];
}

int main() {
//	freopen("D.in", "r", stdin);
	scanf("%d%d%d", &n, &m, &k);

	memset(h, -1, sizeof h);
	while (m--) {
		int u, v, a;
		scanf("%d%d%d", &u, &v, &a);
		add(u, v, a);
	}

	printf("%d\n", spfa());

	return 0;
}

延申阅读

这类图有一个细化分类,叫做同余最短路。对于同余最短路还有动态规划的解法:

同余最短路的转圈技巧 - qAlex_Weiq - 博客园

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

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

相关文章

React系列教程(2)React哲学

豆约翰习惯将掌握某一技术分为5个层次&#xff1a;初窥门径&#xff0c;小试牛刀&#xff0c;渐入佳境&#xff0c;得心应手&#xff0c;玩转自如 本篇属于React框架中的第1层次即初窥门径 我们认为&#xff0c;React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方…

「Mac畅玩鸿蒙与硬件29」UI互动应用篇6 - 多选问卷小应用

本篇将带你实现一个多选问卷小应用&#xff0c;用户可以勾选选项并点击提交按钮查看选择的结果。通过本教程&#xff0c;你将学习如何使用 Checkbox 组件、动态渲染列表、状态管理及用户交互&#xff0c;构建完整的应用程序。 关键词 UI互动应用Checkbox 组件状态管理动态列表…

【linux 多进程并发】0203 网络资源的多进程处理,子进程完全继承网络套接字,避免“惊群”问题

0203 网络资源的多进程处理 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 一、概…

江协科技STM32学习- P32 MPU6050

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

程序设计方法与实践-时空权衡

什么是时空权衡&#xff1f; 时空权衡是算法设计中的一个众所周知的问题&#xff0c;也就是对算法的空间和时间效率做出权衡&#xff0c;它大概有分两种形式&#xff1a; 对输入的部分数据或者全部数据作预处理&#xff0c;然后对于获得额外信息储存起来&#xff0c;从而加快…

STM32F1学习——TIM

一、STM32中的定时器 在STM32中分为三种定时器&#xff0c;分别是基本定时器&#xff0c;通用定时器和高级定时器&#xff0c;每种定时器都是向下兼容的。 二、定时器详细介绍 a、基本定时器 基本定时器主要由下面与分频器、计数器 和 自动重装寄存器三个组成的时基单元&#…

W5500-EVB-Pico2评估板介绍

目录 1 概述 2 板载资源 2.1 硬件规格 2.2 硬件规格 2.3 工作条件 3 参考资料 3.1 RP2350 数据手册 3.2 W5500 数据手册 3.3 原理图 原理图 & 物料清单 & Gerber 文件 3.3 尺寸图 (单位 : mm) 3.4 参考例程 认证 CE FCC AWS 资质 Microsoft Azure 认证…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十二:在屏幕上显示多路视频播放,可以有不同的分辨率,格式和帧率。

上图是在安防领域的要求&#xff0c;一般都是一个屏幕上有显示多个摄像头捕捉到的画面&#xff0c;这一节&#xff0c;我们是从文件中读取多个文件&#xff0c;显示在屏幕上。

Oracle视频基础1.4.3练习

15个视频 1.4.3 できない dbca删除数据库 id ls cd cd dbs ls ls -l dbca# delete a database 勾选 # chris 勾选手动删除数据库 ls ls -l ls -l cd /u01/oradata ls cd /u01/admin/ ls cd chris/ ls clear 初始化参数文件&#xff0c;admin&#xff0c;数据文件#新版本了…

一个由Deno和React驱动的静态网站生成器

大家好&#xff0c;今天给大家分享一个由 Deno React 驱动的静态网站生成器Pagic。 项目介绍 Pagic 是一个由 Deno React 驱动的静态网站生成器。它配置简单&#xff0c;支持将 md/tsx 文件渲染成静态页面&#xff0c;而且还有大量的官方或第三方主题和插件可供扩展。 核心…

1分钟解决Excel打开CSV文件出现乱码问题

一、编码问题 1、不同编码格式 CSV 文件有多种编码格式&#xff0c;如 UTF - 8、UTF - 16、ANSI 等。如果 CSV 文件是 UTF - 8 编码&#xff0c;而 Excel 默认使用的是 ANSI 编码打开&#xff0c;就可能出现乱码。例如&#xff0c;许多从网络应用程序或非 Windows 系统生成的 …

发布天工AI高级搜索功能,昆仑万维做最懂科研学术的AI搜索

今天&#xff0c;昆仑万维天工AI正式发布最新版本的AI高级搜索功能。 一年时光&#xff0c;栉风沐雨。昆仑万维致力于通过领先的AI技术&#xff0c;为全球用户提供创新的智能搜索和信息处理解决方案。无论是金融、科技领域的专业搜索还是文档分析&#xff0c;「天工AI高级搜索…

mac找到主目录下的文件夹

访达-&#xff08;上方状态栏显示&#xff09;-然后在

安装fpm,解决*.deb=> *.rpm

要从生成 .deb 包转换为 .rpm 包&#xff0c;可以按照以下步骤修改打包脚本 1. 使用 fpm 工具 fpm 是一个强大的跨平台打包工具&#xff0c;可以将 .deb 包重新打包成 .rpm&#xff0c;也可以直接从源文件打包成 .rpm。 安装 fpm sudo apt-get install ruby-dev sudo gem in…

分布式光伏管理办法

随着分布式光伏项目的不断增加&#xff0c;传统的管理方式已经难以满足高效、精准的管理需求。光伏业务管理系统作为一种集信息化、智能化于一体的管理工具&#xff0c;正在逐步成为分布式光伏项目管理的重要支撑。 光伏业务管理系统通过数字化手段实现对光伏业务全流程的精细化…

数据结构:LRUCache

什么是LRUCache 首先我们来看看什么是cache 缓存&#xff08;Cache&#xff09;通常用于两个速度不同的介质之间&#xff0c;以提高数据访问的速度和效率。这里有几个典型的应用场景&#xff1a; 处理器和内存之间&#xff1a; 处理器&#xff08;CPU&#xff09;的运算速度远…

智能提醒助理系列-springboot项目彩虹日志+TraceID

本系列文章记录“智能提醒助理”产品建设历程&#xff0c;记录实践经验、巩固知识点、锻炼总结能力。 本篇介绍如何让springboot启动日志“彩打” 提升日志识别度&#xff0c;同时增加TraceID&#xff0c;便于同一请求&#xff0c;全链路的追踪。 一、需求出发点 提升日志识别度…

窨井监测遥测终端RTU IP68防水强信号穿透力

在窨井的潮湿 黑暗和腐蚀性环境中 常规物联网设备往往难以生存 如何突破层层环境挑战 轻松应对极端条件 确保信号 24h不掉线&#xff0c;不延迟 不仅是对技术的突破 更是对恶劣环境的征服 ↓↓↓ 坚守 ——严苛环境下的工业设备 计讯物联工业级设备&#xff0c;专为恶劣环境设计…

150道MySQL高频面试题,学完吊打面试官--如何实现索引机制

前言 本专栏为150道MySQL大厂高频面试题讲解分析&#xff0c;这些面试题都是通过MySQL8.0官方文档和阿里巴巴官方手册还有一些大厂面试官提供的资料。 MySQL应用广泛&#xff0c;在多个开发语言中都处于重要地位&#xff0c;所以最好都要掌握MySQL的精华面试题&#xff0c;这也…

基于Matlab 模拟停车位管理系统【源码 GUI】

系统对进入停车位的车辆进行车牌识别&#xff0c;将识别出来的车牌号显示出来&#xff1b;然后对车主进行人脸识别&#xff0c;框出车主照片的人脸部分作为车主信息的标记&#xff0c;记录在系统库中。车辆在库期间&#xff0c;系统使用者可以随意查看车辆与车主信息的获取过程…