Codeforces Round 637 (Div. 1)___C. Nastya and Unexpected Guest —— 01bfs

题目链接:点我啊╭(╯^╰)╮

题目大意:

    有 m m m 个休息站,起点为 d 1 d_1 d1,终点为 d m d_m dm
    绿灯时间为 g g g,绿灯时间内必须一直走
    红灯时间为 r r r,禁止走,且红灯时间内必须在休息站
    只有在休息站内可以调整方向,红绿灯交替
    求最短时间

解题思路:

     d p [ i ] [ j ] dp[i][j] dp[i][j] 为到达 i i i 这个休息站,绿灯时间为 j j j,经历了最少的红灯次数
    这样转移的边权只能是 + 1 ( j = = g ) +1(j==g) +1j==g,或者 + 0 ( j < g ) +0(j<g) +0j<g
    就可以用 d e q u e deque deque 维护 01 b f s 01bfs 01bfs 来解决
    边权为 1 1 1 的放在队尾,边权为 0 0 0 的放在队首
    注意不能在结束的时候再计算答案,可能会多计算一次红灯

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
const int maxn = 1e4 + 5;
const int maxm = 1e3 + 5;
int n, d[maxn], g, r;
int dp[maxn][maxm];
bool vis[maxn][maxm];
struct node {
	int p, g, r;
};
deque <node> q;
 
void go(node u, int v) {
	if(v < 1 || v > n) return;
	int dis = abs(d[u.p] - d[v]);
	if(u.g + dis > g) return;
	assert(u.r == dp[u.p][u.g]);
	if(u.g + dis == g) {
		if(!vis[v][0]) {
			dp[v][0] = u.r + 1; vis[v][0] = 1;
			q.push_back({v, 0, u.r + 1});
		}
	} else {
		int ng = u.g + dis;
		if(!vis[v][ng]) {
			dp[v][ng] = u.r; vis[v][ng] = 1;
			q.push_front({v, ng, u.r});
		}
	}
}
 
signed main() {
	scanf("%d%d", &n, &n);
	for(int i=1; i<=n; i++) scanf("%d", d+i);
	scanf("%d%d", &g, &r); sort(d+1, d+1+n);
	dp[1][0] = 0; vis[1][0] = 1;
	q.push_front({1, 0, 0});
	ll ans = 1e18;
	while(q.size()) {
		node u = q.front(); q.pop_front();
		if(u.g == 0 && d[n] - d[u.p] <= g) 
			ans = min(ans, 1ll * dp[u.p][u.g] * (g + r) + d[n] - d[u.p]);
		go(u, u.p - 1), go(u, u.p + 1);
	}
	printf("%lld\n", ans == 1e18 ? -1ll : ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,Codeforces Round 511 (Div. 1)是一个比赛的名称。然而,引用内容中没有提供与这个比赛相关的具体信息或问题。因此,我无法回答关于Codeforces Round 511 (Div. 1)的问题。如果您有关于这个比赛的具体问题,请提供更多的信息,我将尽力回答。 #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Codeforces Round 867 (Div. 3)(A题到E题)](https://blog.csdn.net/wdgkd/article/details/130370975)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值