牛客练习赛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

输入

复制

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去切换模式。

思路:

作者: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';
        }
    }
}