首页 > 其他分享 >[CSP-J 2023] 旅游巴士

[CSP-J 2023] 旅游巴士

时间:2023-12-21 20:22:45浏览次数:47  
标签:10 int dd leq 巴士 2023 景区 CSP dis

题目描述

小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。

旅游景点的地图共有 \(n\) 处地点,在这些地点之间连有 \(m\) 条道路。其中 \(1\) 号地点为景区入口,\(n\) 号地点为景区出口。我们把一天当中景区开门营业的时间记为 \(0\) 时刻,则从 \(0\) 时刻起,每间隔 \(k\) 单位时间便有一辆旅游巴士到达景区入口,同时有一辆旅游巴士从景区出口驶离景区。

所有道路均只能单向通行。对于每条道路,游客步行通过的用时均为恰好 \(1\) 单位时间。

小 Z 希望乘坐旅游巴士到达景区入口,并沿着自己选择的任意路径走到景区出口,再乘坐旅游巴士离开,这意味着他到达和离开景区的时间都必须是 \(k\) 的非负整数倍。由于节假日客流众多,小 Z 在旅游巴士离开景区前只想一直沿着景区道路移动,而不想在任何地点(包括景区入口和出口)或者道路上停留

出发前,小 Z 忽然得知:景区采取了限制客流的方法,对于每条道路均设置了一个
“开放时间”\(a _ i\),游客只有不早于 \(a _ i\) 时刻才能通过这条道路。

请帮助小 Z 设计一个旅游方案,使得他乘坐旅游巴士离开景区的时间尽量地早。

输入格式

输入的第一行包含 3 个正整数 \(n, m, k\),表示旅游景点的地点数、道路数,以及旅游巴士的发车间隔。

输入的接下来 \(m\) 行,每行包含 3 个非负整数 \(u _ i, v _ i, a_ i\),表示第 \(i\) 条道路从地点 \(u _ i\) 出发,到达地点 \(v _ i\),道路的“开放时间”为 \(a _ i\)。

输出格式

输出一行,仅包含一个整数,表示小 Z 最早乘坐旅游巴士离开景区的时刻。如果不存在符合要求的旅游方案,输出 -1

样例 #1

样例输入 #1

5 5 3
1 2 0
2 5 1
1 3 0
3 4 3
4 5 1

样例输出 #1

6

提示

【样例 #1 解释】

小 Z 可以在 \(3\) 时刻到达景区入口,沿 \(1 \to 3 \to 4 \to 5\) 的顺序走到景区出口,并在 \(6\) 时刻离开。

【样例 #2】

见附件中的 bus/bus2.inbus/bus2.ans

【数据范围】

对于所有测试数据有:\(2 \leq n \leq 10 ^ 4\),\(1 \leq m \leq 2 \times 10 ^ 4\),\(1 \leq k \leq 100\),\(1 \leq u _ i, v _ i \leq n\),\(0 \leq a _ i \leq 10 ^ 6\)。

测试点编号 \(n \leq\) \(m \leq\) \(k \leq\) 特殊性质
\(1 \sim 2\) \(10\) \(15\) \(100\) \(a _ i = 0\)
\(3 \sim 5\) \(10\) \(15\) \(100\)
\(6 \sim 7\) \(10 ^ 4\) \(2 \times 10 ^ 4\) \(1\) \(a _ i = 0\)
\(8 \sim 10\) \(10 ^ 4\) \(2 \times 10 ^ 4\) \(1\)
\(11 \sim 13\) \(10 ^ 4\) \(2 \times 10 ^ 4\) \(100\) \(a _ i = 0\)
\(14 \sim 15\) \(10 ^ 4\) \(2 \times 10 ^ 4\) \(100\) \(u _ i \leq v _ i\)
\(16 \sim 20\) \(10 ^ 4\) \(2 \times 10 ^ 4\) \(100\)

题解

对于这个题而言,我们要在图上走一下,走出k的整数倍的路径长度,求这样的问题应该如何解?比如下图,

如果K为5的话,显然我们转一圈会更好,所以说,对于每个点来说,我们并不是要求最短路路径,当然,遇到这个k的整数倍的问题,我们知道一定是和模有关,但是这个模要怎么用?我一只思考不明白这个问题,
正确的想法是,同时也是一般的设计想法是,我们把模设计到状态中,dis[u][x]表示到达u的在模k意义下为x的最短路径,我们正常去跑最短路即可,最终目标状态是dis[n][0],我们用迪杰斯特拉的思路来写就行。问题来了,这样的写法,时间复杂度是多少?
我们可以来类比迪杰斯特拉的时间复杂度分析
对于每一条边,他的终端v,会有k次进队的机会,所以进队的操作是mklognk,删除堆顶的操作为nklognk,随意最终的时间复杂度为(mk+nk)lognk

但是第一次我写错了,一直T,哪里写错了呢?

点击查看代码
        int u=q.top().u;
        int y=q.top().ys;
        int dd=q.top().dis;
        if(u==n&&y==0){
            ans=dd;
            return;
        }
        
        if(b[u][y]) continue;
        b[u][y]=1;
        
        q.pop();//这里写错了,如果这么写的话,如果访问过了,就continue了,就不会pop出去了,这里导致我一直T,记住

最终AC代码:

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=10005;
const int maxm=20005;
struct Edge{
    int to,nxt,ai;
}ed[maxm];
int n,m,k,head[maxn],ecnt,ans=2147483647;
void addedge(int u,int v,int ai){
    ed[++ecnt].to=v;
    ed[ecnt].ai=ai;
    ed[ecnt].nxt=head[u];
    head[u]=ecnt;
}
struct node{
    int dis,u,ys;
    bool operator<(node s)const{
        return dis>s.dis;
    }
    node(int a,int b,int c){
        dis=a;
        u=b;
        ys=c;
    }
};
priority_queue< node >q;
int dis[maxn][105];
bool b[maxn][105];
void bfs(){
    q.push(node(0,1,0));
    memset(dis,0x3f,sizeof dis);
    dis[1][0]=0;
    while(!q.empty()){
        int u=q.top().u;
        int y=q.top().ys;
        int dd=q.top().dis;
        if(u==n&&y==0){
            ans=dd;
            return;
        }
        q.pop();
        if(b[u][y]) continue;
        b[u][y]=1;
        for(int i=head[u];i;i=ed[i].nxt){
            int v=ed[i].to;
            int bs;
            if(ed[i].ai>dd){
                bs=ceil((ed[i].ai-dd)*1.0/k);//早出发多少倍
            }else bs=0;
            int yy=(dd+1)%k;
            if(dis[v][yy]>dd+1+bs*k){
                dis[v][yy]=dd+1+bs*k;
                q.push(node(dd+1+bs*k,v,yy));
            }
        }
    }
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        addedge(a,b,c);
    }
    bfs();
    if(ans==2147483647) printf("-1");
    else printf("%d",ans);
    return 0;
}
/**
9 14 95
7 9 0
6 9 0
4 2 0
3 4 0
5 7 0
7 9 0
8 7 0
5 3 0
8 7 0
1 6 0
5 3 0
2 8 0
3 1 0
6 5 0
 */

标签:10,int,dd,leq,巴士,2023,景区,CSP,dis
From: https://www.cnblogs.com/sdfzls/p/17920004.html

相关文章

  • SciTech-OS-MacOS的CSP(System Integrity Protection)系统正直性保护系统
    bash-3.2#csrutilusage:csrutil<command>ModifytheSystemIntegrityProtectionconfiguration.Allconfigurationchangesapplytotheentiremachine.Availablecommands:clearCleartheexistingconfiguration.disableDis......
  • 【2023CANN训练营第二季】——Ascend C代码实操分享
    1.实操题目:使用AscendC实现Addcdiv算子参考pytorch的Addcdiv算子,实现AscendC算子Addcdiv,算子命名为AddcdivCustom相关算法:out=x+y/z*value要求:1、完成Kernel侧实现代码和host侧调用算子代码,支持fp16类型输入2、完成AcInn方式调用编写好的算子3、根据提供的测试用例,使用......
  • 2023.12.21——每日总结
    学习所花时间(包括上课):9h代码量(行):0行博客量(篇):1篇今天,上午学习,下午学习;我了解到的知识点:1.设计模式明日计划:学习......
  • 360沃通亮相2023年深圳市卫生健康信息学术会议,展示医疗行业商密应用方案
    2023年12月15日-16日,深圳市卫生健康信息协会举办主题为“智慧健康引领网络安全护航”的2023年深圳市卫生健康信息学术会议暨“京沪宁深连线”深圳专场,360沃通作为深圳密码领域代表性企业受邀参会,与现场知名专家学者、卫生健康信息化业内同仁、卫生健康信息产品厂商展开深入交流,并......
  • 2023最新高级难度C语言面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-高级难度C语言面试题合集问:在C语言中,如何使用结构体进行面向对象编程?在C语言中,虽然没有像C++或Java那样的类和对象概念,但可以通过结构体、函数指针和其他技术来模拟面向对象编程的某些特性。以下是一些使用结构体进行面向对象编程的关......
  • 2023最新中级难度C语言面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-中级难度C语言面试题合集问:在C语言中,如何使用指针访问数组的各个元素?在C语言中,数组名实际上是一个指向数组第一个元素的指针。因此,我们可以使用指针算术来访问数组的各个元素。下面是一个示例代码,演示如何使用指针访问数组的各个元素:......
  • Databend 开源社区上榜 2023 年度 OSCHINA 优秀开源技术团队
    2023年12月8日,OSCHINA对其平台上众多认证的官方技术团队和开源社区进行了全面评估,并颁发了“2023年度优秀开源技术团队”奖项,以表彰各团队在推动中国开源生态系统发展方面所展现的创新能力和显著贡献。在这一评选中,Databend开源社区有幸获得了2023年度优秀开源技术团......
  • 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.21)
    一、百度网盘SVIP超级会员共享账号可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答。我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免了U盘的物理载体,直接在网上就实现文件传输。百度网盘SVIP会员可以让自己百度账......
  • TDengine 创始人陶建辉亮相 EDT2023 峰会,分享工业数据处理平台的创新实践
    随着大数据、物联网、人工智能、5G等数字技术的蓬勃发展,能源化工行业与新兴技术也在加速融合,推动着智能化、网格化和信息化进程的加速演进。在不稳定的外部环境下,数字化转型成为能源化工企业实现可持续发展的关键。12月14日,勤哲文化主办的“EDT2023中国能源化工数字科技峰会......
  • 实验七 周天意 202383290417
    实验七1.实验任务1:文本文件格式化读/写验证性实验。task1_1.c把程序中的图书信息数据,写入文本文件data1.txt中task1_2.c从文件data1.txt读入数据,并在屏幕上打印输出在C编程环境下,依次输入task1_1.c和task1_2.c,结合程序运行结果,理解代码,掌握文件打开/关闭、格式化读写操作......