P9751 [CSP-J 2023] 旅游巴士

P 9751 P9751 P9751

部分分思路

题目要求时间必须是 k k k 的非负整数倍,所以想到了升维 。这样就变成了一道分层图最短路 的题目。用 BFS 算法可以拿到 A i = 0 A_i=0 Ai=0 的 35 35 35 分。

满分思路

其实部分分的思路已经很接近正解了,想要拿到满分只需要做一点小小的调整。虽然说不能在路上停留,但是我们可以晚一点到达起点 。但是要注意:到达起点的时间也必须是 k k k 的倍数。这个做法 BFS 就解决不了了(它只能解决出发时间相同且边权为 1 1 1 的最短路问题),我们可以使用 Dijkstra 算法来解决这道题。时间复杂度约 O ( O( O( n n n + + + m ⋅ l o g 2 m m \cdot log_2m m⋅log2m ) ) )。

代码

cpp 复制代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
const int INF = 0x3f3f3f3f; // 极大值∞

int n, m, k;
int dis[10010][110]; // 最短路
int vis[10010][110]; // 记录点有没有被选过

struct edge // 边
{
	int y, w;
} ;

struct node // 优先队列中的点
{
	int x, t, d;
	
	bool operator < (const node b) const // 重载运算符
	{
		return d > b.d;
	}
} ;

vector<edge> g[10010]; // 图

void add(int x, int y, int w) // 建边
{
	g[x].push_back({y, w});
}

void dijkstra(int s) // dijkstra算法,堆优化
{
	priority_queue<node> q;
	memset(dis, 0x3f, sizeof(dis));
	q.push({s, 0, 0});
	dis[s][0] = 0;
	while (q.size())
	{
		int x = q.top().x;
		int t = q.top().t;
		q.pop();
		if (vis[x][t])
			continue;
		vis[x][t] = 1;
		int nt = (t + 1) % k;
		for (int i = 0; i < g[x].size(); i++)
		{
			int y = g[x][i].y;
			int w = g[x][i].w;
			int d = dis[x][t];
			if (d < w) d += (w - d + k - 1) / k * k; // 到达起点时间
			if (dis[y][nt] > d + 1)
			{
				dis[y][nt] = d + 1;
				q.push({y, nt, dis[y][nt]});
			}
		}
	}
}

int main()
{
	cin >> n >> m >> k;
	for (int i = 1; i <= m; i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		add(u, v, w); // 建条单向边
	}
	dijkstra(1);
	if (dis[n][0] == INF)
		cout << "-1" << endl; // 无解
	else cout << dis[n][0] << endl;
	return 0;
}
相关推荐
如意.7592 分钟前
【C++】—— map 与 set 深入浅出:设计原理与应用对比
开发语言·c++
CodeAllen嵌入式3 分钟前
嵌入式面试题练习 - 2024/11/15
数据结构·windows·嵌入式硬件·算法·嵌入式·嵌入式系统
起名字真南28 分钟前
【C++】深入理解自定义 list 容器中的 list_iterator:迭代器实现详解
数据结构·c++·windows·list
蹊黎32 分钟前
C++模版初阶
开发语言·c++
DongGei33 分钟前
c++多线程
c++
不去幼儿园34 分钟前
【SSL-RL】自监督强化学习: 好奇心驱动探索 (CDE)算法
大数据·人工智能·python·算法·机器学习·强化学习
YYDS31437 分钟前
C++各类函数评点+详解
开发语言·数据结构·c++·算法·贪心算法·动态规划
SaNDJie38 分钟前
24.11.13 机器学习 特征降维(主成份分析) KNN算法 交叉验证(K-Fold) 超参数搜索
人工智能·算法·机器学习
小鱼仙官2 小时前
MFC中Picture Control控件显示照片的几种方式
c++·mfc
cleverpeople3 小时前
11.15作业
c语言·开发语言·算法