首页 > 其他分享 >Codeforces 1801D The way home

Codeforces 1801D The way home

时间:2023-06-06 19:11:07浏览次数:42  
标签:vdis int Codeforces long wh second way home mx

看到 shortest paths 来做的。

首先有一个贪心的策略,对于当前点 \(u\) 若不能直接往后走则肯定是选择经过的点中 \(w_i\) 最大的加。
很好理解,证明就不需要了。
所以可以定义状态 \(f_{u, mx}\) 为 \(u\) 点最大能加的值为 \(h_{mx}\) 的最优状态,\(h\) 是 \(w\) 离散化后的数组。

接下来考虑最优状态要在哪些位置上优:
首先因为答案跟次数有关,所以肯定次数 \(c\) 会是之一,其次,若 \(c\) 相同,则肯定是走完上一条边剩的金钱越多越好(注意走一条边剩下的金钱肯定小于上一个状态对应的 \(h'_{mx}\),因为到了 \(u\) 后 \(h_{mx} \ge h'_{mx}\),则在前面选的更多肯定不优),所以剩下的金钱 \(s\) 也要算上。
综合一下,则要满足 \(c\) 最小的同时 \(s\) 最大。
大致证一下为什么这么选择:

  1. \(c = c', s > s'\),这肯定选择 \((c, s)\);
  2. \(c < c'\),则因为 \(s, s' < h'_{mx} \ge h_{mx}\),所以 \(s + (c' - c)\times h_{mx} > h'_{mx}\),所以选择 \((c, s)\)。

然后发现这个 \((c, s)\) 的状态放在图上可以当做最短路来跑,直接跑就行。

时间复杂度 \(\mathcal{O}(T(nm\log_2 nm))\)。

// lhzawa(https://www.cnblogs.com/lhzawa/)
#include<bits/stdc++.h>
using namespace std;
const int N = 8e2 + 10;
const long long inf = 0x3f3f3f3f3f3f;
pair<long long, long long> dis[N][N];
bool vis[N][N];
vector<pair<int, long long> > ev[N];
long long w[N], wp[N];
int wh[N];
int main() {
	int Tcs;
	cin >> Tcs;
	function<void ()> solve = []() -> void {
		int n, m;
		long long st;
		scanf("%d%d%lld", &n, &m, &st);
		function<void ()> clears = [n]() -> void {
			for (int i = 1; i <= n; i++) {
				ev[i].clear();
			}
			for (int i = 1; i <= n; i++) {
				for (int j = 1; j <= n; j++) {
					vis[i][j] = 0, dis[i][j] = {inf, inf};
				}
			}
			return ;
		};
		clears();
		for (int i = 1; i <= n; i++) {
			scanf("%lld", &w[i]);
			wp[i] = w[i];
		}
		sort(wp + 1, wp + n + 1);
		for (int i = 1; i <= n; i++) {
			wh[i] = lower_bound(wp + 1, wp + n + 1, w[i]) - wp;
		}
		function<void (int, int, long long)> add = [](int x, int y, long long z) -> void {
			ev[x].push_back({y, z});
			return ;
		};
		for (int i = 1; i <= m; i++) {
			int x, y;
			long long z;
			scanf("%d%d%lld", &x, &y, &z);
			add(x, y, z);
		}
		dis[1][wh[1]] = {0, st};
		priority_queue<pair<pair<long long, long long>, pair<int, int> > > q;
		q.push({{-0, st}, {1, wh[1]}});
		for (; ! q.empty(); ) {
			pair<pair<long long, long long>, pair<int, int> > tp = q.top();
			q.pop();
			int u = tp.second.first, mx = tp.second.second;
			// printf("<- %d %d\n", u, mx);
			if (vis[u][mx]) {
				continue;
			}
			vis[u][mx] = 1;
			// printf("%d %d %lld %lld\n", u, mx, dis[u][mx].first, dis[u][mx].second);
			for (unsigned i = 0; i < ev[u].size(); i++) {
				int v = ev[u][i].first;
				long long y = ev[u][i].second;
				long long c = max(0ll, y - dis[u][mx].second);
				long long p = c / wp[mx] + (c % wp[mx] > 0);
				pair<long long, long long> vdis = {dis[u][mx].first + p, dis[u][mx].second + p * wp[mx] - y};
				if (vdis.first < dis[v][max(mx, wh[v])].first || (vdis.first == dis[v][max(mx, wh[v])].first && vdis.second > dis[v][max(mx, wh[v])].second)) {
					// printf("-> %d %d %lld %lld\n", v, max(mx, wh[v]), vdis.first, vdis.second);
					dis[v][max(mx, wh[v])] = vdis;
					q.push({{-vdis.first, vdis.second}, {v, max(mx, wh[v])}});
				} 
			}
		}
		long long ans = inf;
		for (int i = 1; i <= n; i++) {
			// printf("%d %lld %lld\n", i, dis[n][i].first, dis[n][i].second);
			ans = min(ans, dis[n][i].first);
		}
		printf("%lld\n", ans == inf ? -1 : ans);
		return ;
	};
	for (; Tcs; Tcs--) {
		solve();
	}
	return 0;
}

标签:vdis,int,Codeforces,long,wh,second,way,home,mx
From: https://www.cnblogs.com/lhzawa/p/17461473.html

相关文章

  • Codeforces 1588F - Jumping Through the Array
    显然无法用polylog的数据结构维护,序列分块也不行,考虑询问分块。每\(B\)个询问处理一次。将这个询问中\(2,3\)操作涉及到的点设为“关键点”,那么容易发现,环上每一段以关键点结尾的链在这块操作的过程中始终保持不变,也就是说我们可以把它们缩在一起。先预处理出每个块的增量......
  • Codeforces 1495F - Squares
    不知道怎么放到div1F的,感觉没啥亮点。首先对于一条\(1\)到\(n+1\)的路径而言,它经过的点的编号一定是递增的,也就是说,如果我们将关键点大小排个序,那么答案就是相邻两点间最短路的和。删/加点造成的变化是\(O(1)\)的,所以问题等价于,多次询问这张图中\(x,y\)之间最短路的......
  • Failed to load resource: xxx 504 (Gateway Time-out)
    问题描述:上传文件js,报错如下:Failedtoloadresource:theserverrespondedwithastatusof504(GatewayTime-out) 问题原因:网络超时 解决办法:nginx配置 proxy_read_timeout150;location/{proxy_read_timeout150;//单位为秒}就是把超时时间调长一点,保证......
  • day08-SpringCloud Gateway-服务网关
    SpringCloudGateway-服务网关1.Gateway介绍1.1引出问题没有使用网关服务时:使用网关服务后:1.2Gateway网络拓扑图1.3Gateway是什么官网:SpringCloudGatewayGateway是Spring生态系统之上构建的API网关服务,基于Spring、SpringBoot和ProjectReactor等技术Gateway旨在......
  • Codeforces Round 876 (Div. 2)
    PrefaceDP腐乳闪总出列!(本来以为大掉分的一把,但这个号因为挺新的所以竟然还能上挺多分的,压线完成了5场上紫)早知道去做E题了,感觉CF真得要看题目相性,有些题目就是一眼感觉不适合自己的说A.TheGoodArray一个要动点脑子的签到题,因为\(a_1,a_n\)必须等于\(1\),然后中间的\(n-1\)......
  • Codeforces Round 876 (Div. 2)题解
    CodeforcesRound876(Div.2)A.TheGoodArray标签greedymath题意对于任意\(i\in\{1,2,\dots,n\}\),要求数列\(a\)满足前\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\),后\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\)。思......
  • 2023.5 codeforces 杂题选做
    2023.5codeforces杂题选做E.Location\(n\le5\times10^4\)的范围,并且区间赋值、区间维护最值,可以考虑分块。然后对于散块的修改可以直接暴力,对于整块,由于\(b_i\)值不变,\(a_i\)值只有一个,思考如何快速求。由于\(\dfrac{\operatorname{lcm}(a_i,b_i)}{\gcd(a_i,b_i)}=\d......
  • Homebrew游戏和独立游戏的区别
    Homebrew游戏和独立游戏是游戏开发领域中的两个概念,它们之间存在一些区别。开发者身份:Homebrew游戏通常由游戏玩家或游戏爱好者开发,他们使用自己的技能和资源制作游戏,通常是为了个人乐趣或共享给其他玩家。独立游戏则是由专业的独立游戏开发者或小型游戏开发团队制作,他们追求商业......
  • MySQL 8错误日志出现"The table /home/work/mysql_3306/tmp/#sqla2b_298b06_4d is fu
    ##############    了解MySQL8.0.26的错误日志出现"Thetable /home/work/mysql_3306/tmp/#sqla2b_298b06_4disfu11!"的bug,暂时通过修改临时表的存储引擎为内存引擎解决  MySQL8.0.13开始引入新的临时内存表引擎TempTable,并将其作为内存中创建临时表的默认存储引擎。T......
  • 聊聊Spring Cloud Gateway
    网关概述整体来看,网关有点类似于门面,所有的外部请求都会先经过网关这一层。网关不仅只是做一个请求的转发及服务的整合,有了网关这个统一的入口之后,它还能提供以下功能。针对所有请求进行统一鉴权、限流、熔断、日志。协议转化。针对后端多种不同的协议,在网关层统一处理后以HT......