牛客练习赛50 D tokitsukaze and Event (最短路,思维)
牛客练习赛50 D tokitsukaze and Event
链接:https://ac.nowcoder.com/acm/contest/1080/D来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
这天,tokitsukaze带着她的舰队去才归一儿海探索。这个海域有n个站点,深海舰队控制着这片海域的m条航线,这些航线连接着这n个点,第i条航线连接着ui,vi两个点。航线都是正确的,也就是说没有重复的航线,也没有任何一个点与自己相连。tokitsukaze的舰队经过第i条航线时,会受到来自深海舰队的ai点伤害。
tokitsukaze可以在某个休息站点将接下来的战斗切换至夜战模式,这样在她的舰队经过第i条航线时,受到的伤害就变为bi,不过一旦切换到夜战模式就不能再次切换回来,所以她必须考虑清楚在哪里切换。
现在有个限时活动。活动难度分为1,2,3,4,...n,在难度1下,tokitsukaze可以在任意站点切换到夜战模式,而在难度2下,不能在站点1切换到夜战模式,在难度3下,不能在站点1,2切换模式...以此类推,即在难度k下,tokitsukaze不能在站点1,2,3,4,5...k-1切换模式。同时,活动还要求在游戏结束时必须处于夜战模式。
现在tokitsukaze的舰队从s点出发,要前往深海大本营所在的t点。请你告诉她,在难度为1,2,3,4,5...n时,她的舰队结束游戏时受到的最小伤害。
输入描述:
第一行包括2个正整数n,m,(2≤n≤10^5,1≤m≤min(n*(n-1)/2,10^5))。接下来m行,每行包括4个正整数u,v,a,b,(1≤u,v≤n,1≤a,b≤10^9)。最后一行包括2个正整数s,t,(1≤s,t≤n)。
输出描述:
请你告诉tokitsukaze,在难度为1,2,3,4,5...n时,她的舰队处于夜战模式结束游戏受到的最小伤害。
示例1
输入
[复制](javascript:void(0)😉
4 3
1 4 1 30
1 2 1 10
1 3 20 1
2 3
输出
[复制](javascript:void(0)😉
2
11
21
33
说明
活动难度为1时,在编号为1的点切换模式,受到的最小伤害为2。活动难度为2时,在编号为2的点切换模式,受到的最小伤害为11。活动难度为3时,在编号为3的点切换模式,受到的最小伤害为21。活动难度为4时,在编号为4的点切换模式,受到的最小伤害为33。
示例2
输入
[复制](javascript:void(0)😉
4 3
1 4 30 1
1 2 10 1
1 3 20 1
3 1
输出
[复制](javascript:void(0)😉
1
1
1
51
说明
活动难度为1时,在编号为3的点切换模式,受到的最小伤害为1。活动难度为2时,在编号为3的点切换模式,受到的最小伤害为1。活动难度为3时,在编号为3的点切换模式,受到的最小伤害为1。活动难度为4时,在编号为4的点切换模式,受到的最小伤害为51。路线是3-1-4-1。因为必须处于夜战模式结束游戏,所以在到达1后还要拐去4去切换模式。
思路:
作者:tokitsukaze
链接:https://ac.nowcoder.com/discuss/231978?type=101&order=0&pos=3&page=1
来源:牛客网
s为起点,用边权a跑一遍最短路,记为dis_s_a。
把边的方向反转,t为起点,用边权b跑一遍最短路,记为dis_t_b。
那么在节点i切换模式的最小伤害为\(dissa[i] + distb[i]\)
再做一遍后缀min即可。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline void getInt(int* p);
const int maxn = 100010;
const ll inf = 1e18;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node
{
int to;
ll val;
node()
{}
node(int tt, ll vv)
{
to = tt;
val = vv;
}
bool operator < (const node & b) const
{
return val > b.val;
}
};
std::vector<node> va[maxn], vb[maxn];
int n, m;
int s, t;
priority_queue<node> q;
ll dis_s_a[maxn];
void dij1()
{
repd(i, 1, n)
{
dis_s_a[i] = inf;
}
dis_s_a[s] = 0ll;
for (auto x : va[s])
{
q.push(x);
}
node temp;
while (!q.empty())
{
temp = q.top();
q.pop();
for (auto x : va[temp.to])
{
if ( dis_s_a[x.to] > dis_s_a[temp.to] + temp.val)
{
dis_s_a[x.to] = dis_s_a[temp.to] + temp.val;
q.push(node(x.to, dis_s_a[x.to]));
}
}
}
}
ll dis_t_b[maxn];
void dij2()
{
repd(i, 1, n)
{
dis_t_b[i] = inf;
}
dis_t_b[t] = 0ll;
for (auto x : vb[t])
{
q.push(x);
}
node temp;
while (!q.empty())
{
temp = q.top();
q.pop();
for (auto x : vb[temp.to])
{
if ( dis_t_b[x.to] > dis_t_b[temp.to] + temp.val)
{
dis_t_b[x.to] = dis_t_b[temp.to] + temp.val;
q.push(node(x.to, dis_t_b[x.to]));
}
}
}
}
ll dis[maxn];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
du2(n, m);
int x, y, z, w;
repd(i, 1, m)
{
du2(x, y);
du2(z, w);
va[x].push_back(node(y, z));
va[y].push_back(node(x, z));
vb[x].push_back(node(y, w));
vb[y].push_back(node(x, w));
}
du2(s, t);
dij1();
dij2();
repd(i, 1, n)
{
dis[i] = dis_s_a[i] + dis_t_b[i];
}
for (int i = n - 1; i >= 1; --i)
{
dis[i] = min(dis[i], dis[i + 1]);
}
repd(i, 1, n)
{
printf("%lld\n", dis[i]);
}
// dij(dis_s_a);
return 0;
}
inline void getInt(int* p) {
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
}
else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}