【牛客练习赛50】 tokitsukaze and Event

题目描述

这天,tokitsukaze带着她的舰队去才归一儿海探索。这个海域有 n n n个站点,深海舰队控制着这片海域的 m m m条航线,这些航线连接着这 n n n个点,第i条航线连接着 u i u_i ui v i v_i vi两个点。航线都是正确的,也就是说没有重复的航线,也没有任何一个点与自己相连。tokitsukaze的舰队经过第i条航线时,会受到来自深海舰队的 a i a_i ai点伤害。

tokitsukaze可以在某个休息站点将接下来的战斗切换至夜战模式,这样在她的舰队经过第i条航线时,受到的伤害就变为 b i b_i bi,不过一旦切换到夜战模式就不能再次切换回来,所以她必须考虑清楚在哪里切换。

现在有个限时活动。活动难度分为 1 , 2 , 3 , 4 , . . . n 1,2,3,4,...n 1,2,3,4,...n,在难度1下,tokitsukaze可以在任意站点切换到夜战模式,而在难度 2 2 2下,不能在站点 1 1 1切换到夜战模式,在难度 3 3 3下,不能在站点 1 , 2 1,2 1,2切换模式…以此类推,即在难度 k k k下,tokitsukaze不能在站点 1 , 2 , 3 , 4 , 5... k − 1 1,2,3,4,5...k-1 1,2,3,4,5...k1切换模式。同时,活动还要求在游戏结束时必须处于夜战模式。

现在tokitsukaze的舰队从 s s s点出发,要前往深海大本营所在的 t t t点。请你告诉她,在难度为 1 , 2 , 3 , 4 , 5... n 1,2,3,4,5...n 1,2,3,4,5...n时,她的舰队结束游戏时受到的最小伤害。

输入描述:

第一行包括2个正整数 n n n m m m,( 2 ≤ n ≤ 1 0 5 2≤n≤10^5 2n105 1 ≤ m ≤ m i n ( n ∗ ( n − 1 ) / 2 , 1 0 5 ) 1≤m≤min(n*(n-1)/2,10^5) 1mmin(n(n1)/2,105))。
接下来 m m m行,每行包括4个正整数 u , v , a , b u,v,a,b uvab,( 1 ≤ u , v ≤ n 1≤u,v≤n 1u,vn 1 ≤ a , b ≤ 1 0 9 1≤a,b≤10^9 1a,b109)。
最后一行包括2个正整数 s s s t t t,( 1 ≤ s , t ≤ n 1≤s,t≤n 1s,tn)。

输出描述:

请你告诉tokitsukaze,在难度为 1 , 2 , 3 , 4 , 5... n 1,2,3,4,5...n 1,2,3,4,5...n时,她的舰队处于夜战模式结束游戏受到的最小伤害。

示例1

输入

4 3
1 4 1 30
1 2 1 10
1 3 20 1
2 3

输出

2
11
21
33

说明
活动难度为1时,在编号为1的点切换模式,受到的最小伤害为2。
活动难度为2时,在编号为2的点切换模式,受到的最小伤害为11。
活动难度为3时,在编号为3的点切换模式,受到的最小伤害为21。
活动难度为4时,在编号为4的点切换模式,受到的最小伤害为33。

示例2

输入

4 3
1 4 30 1
1 2 10 1
1 3 20 1
3 1

输出

1
1
1
51

说明
活动难度为1时,在编号为3的点切换模式,受到的最小伤害为1。
活动难度为2时,在编号为3的点切换模式,受到的最小伤害为1。
活动难度为3时,在编号为3的点切换模式,受到的最小伤害为1。
活动难度为4时,在编号为4的点切换模式,受到的最小伤害为51。路线是3-1-4-1。因为必须处于夜战模式结束游戏,所以在到达1后还要拐去4去切换模式。

Solution

从起点和终点分别跑最短路

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#define ll long long

using namespace std;

const ll N = 1e5 + 10;
ll n, m, s, t;
ll dis1[N], dis2[N], ans[N];
bool vis[N];

struct edge
{
	ll v, day, night;
};

vector<edge> e[N];

void spfa(ll start, ll* dis, bool isday)
{
	queue<ll> q;
	memset(dis, 0x3f, sizeof dis1);
	memset(vis, 0, sizeof vis);
	q.push(start);
	dis[start] = 0;
	while (q.size())
	{
		ll u = q.front(); q.pop();
		vis[u] = false;
		for (auto i : e[u])
		{
			ll v = i.v, w;
			if (isday) w = i.day; else w = i.night;
			if (dis[u] + w < dis[v])
			{
				dis[v] = dis[u] + w;
				if (!vis[v])
					vis[v] = true, q.push(v);
			}
		}
	}
}

int main()
{
	scanf("%lld%lld", &n, &m);
	for (ll i = 1; i <= m; i++)
	{
		ll u, v, a, b;
		scanf("%lld%lld%lld%lld", &u, &v, &a, &b);
		e[u].push_back({ v, a, b });
		e[v].push_back({ u, a, b });
	}
	scanf("%lld%lld", &s, &t);
	spfa(s, dis1, true); spfa(t, dis2, false);
	memset(ans, 0x3f, sizeof ans);
	for (ll i = n; i; i--)
		ans[i] = min(ans[i + 1], dis1[i] + dis2[i]);
	for (ll i = 1; i <= n; i++)
		printf("%lld\n", ans[i]);

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值