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

P9751 [CSP-J 2023] 旅游巴士 题解

时间:2024-10-22 21:35:48浏览次数:7  
标签:pq P9751 int 题解 cost 时间 2023 include mod

思路

首先,举一个例子,假如说 小Z 到了入口,但是没到时间,所以没法进去,该怎么办?

当然是等 $k$ 个时间单位呀.

除此之外,像到了其他景区,但是还没开门怎么办 ? 继续等 $k$ 的非负整数倍时间呀.

知道这个后,我们先定义状态 $f_{i,j}$,表示到达点 $i$ 时,路径长度(即时间) $mod$ $k$ 的最早时间.

目标:$f_{n,0}$.

为什么要取模呢? 因为这样不仅可以方便计算,而且题面中说到,到达和离开景区的时间均要是 $k$ 的非负整数倍数.所以当 $j=0$ 时,就说明是 $k$ 的倍数了.

转移

显然,这题可以使用最短路,我们在求最短路的同时进行转移.关于最短路算法,建议选择优先队列优化过后的$Dijkstra.$

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>

using namespace std;

int n, m, k;
int f[10004][102]; // f[i][j]表示到点i,长度%k余数为j的最早时间

struct q{
	int id, mod, cost; // 节点编号,j,时间
	bool friend operator < (q a, q b) { // 重载小于运算符
		return a.cost > b.cost;
	}
}; 

struct node {
	int v, w;
};

int vis[10004][102];
vector<node> g[10004]; // vector 存图
priority_queue<q> pq; // 优先队列

void dijkstra() {
	pq.push((q){1, 0, 0}); // 最开始的元素
	while (!pq.empty()) {
		q h = pq.top();
		pq.pop();
		int u = h.id, j = h.mod, cost = h.cost;
        // 没有被访问过,更新 f[u][j]
		if (!vis[u][j]) f[u][j] = cost, vis[u][j] = 1;
		else continue;
		for (int i = 0; i < g[u].size(); i++) {
			int v = g[u][i].v, w = g[u][i].w;
			int t = f[u][j];
			while (t < w) t += k; // 还没有开门,就继续等
			if (t + 1 < f[v][(j+1)%k]) // 更早的时间
				pq.push((q){v, (j+1)%k, t + 1}); // 放入优先队列
		}
	}
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		g[u].push_back((node){v, w});
	}
	memset(f, 0x3f, sizeof(f)); // 初始化,较大的初值
	dijkstra();
	if (f[n][0] != 0x3f3f3f3f) printf("%d", f[n][0]); // 不是初值,说明可以到达
	else printf("-1");
	return 0;
}

标签:pq,P9751,int,题解,cost,时间,2023,include,mod
From: https://www.cnblogs.com/panda-lyl/p/18493786

相关文章

  • P9749 [CSP-J 2023] 公路 题解
    此题贪心食用更佳在输入油价的时候,我们边计算油价的最小值和路程和.当路程之和$>0$时,计算油价并且减去对应路程即可.注意事项要开$long$$long$!!!.代码#include<iostream>#include<cstdio>#include<cmath>#include<cstring>usingnamespacestd;typedeflonglo......
  • P9750 [CSP-J 2023] 一元二次方程 题解
    大模拟此题大模拟即可,只需注意几点:分母$>0$.要给根式化简.分数要约分.求较大根,那就$b^2$加$\bigtriangleup$即可.分母>0因为求根公式中,分母中只有$a$一个未知数,所以我们只需保证$a>0$即可.所以,当$a<0$时,我们把$a,b,c$全部取相反值.但这也是......
  • 题解:P10949 四叶草魔杖
    2024/10/16更新:修改了状态的枚举方式,时间复杂度变为\(O(3^n)\)。题目传送门前言本篇题解默认您已熟练掌握最小生成树、状压dp及其应用,如果您还不会,请先阅读相关博客。分析我们要选出一条边,通过边转移能量,使得所有宝石的能量都为\(0\)。这看上去挺麻烦的,让我们挖掘一......
  • 题解:AT_joisc2019_k 合併 (Mergers)
    题目传送门前言联考题,被初一的我切了。看到题解区里没有Tarjan做法,于是来补一篇Tarjan题解。分析因为相同州的城市不会分裂,所以可以给相同州的成市连边(注意不是两两连边,连成一个环就行),发现把国家分成两个部分就相当于断掉一条道路。那么如果整个国家就是一个边双连通分量,......
  • 题解:P11207 「Cfz Round 9」Rose
    可以考虑把字符串\(s\),\(t\)按\(s_1t_1s_2t_2\dotss_nt_n\)拼接,记为\(a\)。为了方便表述,这里分别把PVW表示为012。Subtask0我会暴力!可以直接在\(a\)上进行dfs,复杂度为\(O(3^{2n})\)。Subtask1我会找性质!注意到答案只有可能是\(0,1,2\),因为在最坏情况下,只......
  • 题解:P11204 「Cfz Round 9」Lone
    首先可以观察出把木棍平均分是最优的。然后平均分后最多只有两种长度的木棒,长度分别为\(\lfloor\frac{m}{n}\rfloor\)和\(\lfloor\frac{m}{n}\rfloor+1\)。最后check一下就行了。代码:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#define......
  • P2934 [USACO09JAN] Safe Travel G 题解
    一个用平衡树,不用脑子的写法。(目前没有用平衡树的诶。)题意不经过最短路的最后一条边的最短路,保证最短路唯一。思路看到最短路唯一容易想到建出的最短路DAG其实是最短路树(以\(1\)为根)。那题意转化为求每个节点不经过与父亲的连边,所能到根节点的最短路。容易发现每个点的......
  • 【NOIP2021】方差 题解
    前言题目链接:洛谷;LOJ;UOJ。题意简述给你单调不降序列\(\{a_n\}\),你可以让\(a_i\getsa_{i-1}+a_{i+1}-a_i\),求操作后方差的最小值。\(n\leq10^4\),\(1\leqa_i\leq600\)。题目分析仔细观察操作,发现实际上是将\(a_i\)按照\(a_{i-1}\)和\(a_{i+1}\)的......
  • 题解:P10977 Cut the Sequence
    题目传送门分析看到这种题就可以想到动态规划,先设状态:$f_i$表示考虑前$i$个数,所需要的最小代价。发现$f_i$可以从所有$i$以前的状态加后一段区间转移过来,于是可以列出状态转移方程:$$f_i=\min_{j=i-1}^{s_i-s_j\leqm}(f_j+\max_{k=j+1}^i)$$其中$j$......
  • 2023期中卷英语错题
    听力(4分):选择题(2分):第一道题:上一道题不会,这道题没有仔细听,一直在想上一道题导致这道题没听清;第二道题:上一道题不会,这道题没有仔细听,一直在想上一道题导致这道题没听清。填词题(2分):第一道题:音频语速太快,没听懂,理解的时候有问题;第二道题:音频语速太快,没听懂,理解的时候有问题。语法(7......