CodeForces

Buy a Ticket

CodeForces - 938D

题目描述

流行乐队“Flayer”宣布,他们想用一次世界巡演来作为他们的收官之作。当然,他们也将来到伯兰演出。

伯兰有 n 个城市。人们可以乘坐双向列车往返于城市之间; 一共有 m 条线路, 第 i 条线路可以从城市 vi 到城市 ui (或者从城市 ui 到城市 vi ),乘坐这条线路需要花费 wi 个硬币。

“Flayer”乐队会到访伯兰的每一个城市,第 i 个城市的音乐会门票要花费 ai 个硬币

你在伯兰的每个城市都有朋友,他们知道你编程很厉害,想让你计算出他们参观音乐会可能要花费的最少的硬币数量。对于每一个城市 i 里的朋友,你都必须计算他从城市 i 前往某个城市 j (或者可能停留在城市 i),参加那里的音乐会,然后返回城市 i (如果 j ≠ i) 所花费的最少硬币数量。

严格来说,对于每一个城市 , d(i, j) 就是你从一个城市 i 到另一个城市 j 所花费的最少的硬币数。 如果没有办法从一个城市 i 到另一个城市 j,那么我们认为 d(i, j) 是无限大的。

输入

第一行包含两个整数 nm (2 ≤ n ≤ 2·105, 1 ≤ m ≤ 2·105).

接下来有 m 行输入,每一行包含 3 个整数 viuiwi (1 ≤ viui ≤ nvi ≠ ui ,1 ≤ wi ≤ 1012) ,表示第 i 条列车路线连接的城市 vi 和城市 ui 以及乘坐列车的车票费用 wi。没有任何的火车线路连接同一对城市,也就是说,如果输入中已经有一对城市 (vu),之后的输入中既没有 (vu) 也没有 (uv) 。

最后一行包含 n 个整数 a1 ,a2, ... ak (1 ≤ ai ≤ 1012) — 代表城市 i 的演唱会票价。

输出

打印 n 个整数。第 i 个数就是一个人从城市 i 前往城市 j (或可能停留在城市 i ), 参加那里的音乐会并返回城市 i (如果 j ≠ i ) 所花费的硬币的最小数量。

样例

输入

4 2
1 2 4
2 3 7
6 20 1 25

输出

6 14 1 25 

输入

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

输出

12 10 12 

分析

首先想到的肯定是暴力,从每一个点开始跑最短路,最后再分别输出结果,但是这样复杂度肯定吃不消

题目中也没有说给出的是一棵树,所以树形DP也不太可行

所以我们考虑建边时做一些处理

我们建一个超级源点跑最短路,和昂贵的聘礼那一道题有点像

对于边权,我们把它乘2再正常建边,因为我们要往返各一次

对于点权,我们从超级源点向该点建一条边,边权为点权,代表在某一个点停留所花费的时间

最后再从超级源点开始跑一个最短路就可以了

不要忘了开long long

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
struct asd{
    ll from,to,next,val;
}b[maxn];
int head[maxn],tot=1;
void ad(ll aa,ll bb,ll cc){
    b[tot].from=aa;
    b[tot].to=bb;
    b[tot].val=cc;
    b[tot].next=head[aa];
    head[aa]=tot++;
}
struct jie{
    ll num,dis;
    jie(ll aa=0,ll bb=0){
        num=aa,dis=bb;
    }
    bool operator < (const jie& A) const{
        return dis>A.dis;
    }
};
priority_queue<jie> q;
ll dis[maxn];
bool vis[maxn];
void DIJ(){
    memset(dis,0x3f,sizeof(dis));
    dis[0]=0;
    q.push(jie(0,0));
    while(!q.empty()){
        int now=q.top().num;
        q.pop();
        if(vis[now]) continue;
        vis[now]=1;
        for(ll i=head[now];i!=-1;i=b[i].next){
            ll u=b[i].to;
            if(dis[u]>dis[now]+b[i].val){
                dis[u]=dis[now]+b[i].val;
                q.push(jie(u,dis[u]));
            }
        }
    }
}
int main(){
    memset(head,-1,sizeof(head));
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=m;i++){
        ll aa,bb,cc;
        scanf("%lld%lld%lld",&aa,&bb,&cc);
        ad(aa,bb,cc*2ll);
        ad(bb,aa,cc*2ll);
    }
    for(ll i=1;i<=n;i++){
        ll aa;
        scanf("%lld",&aa);
        ad(0,i,aa);
    }
    DIJ();
    printf("%lld",dis[1]);
    for(ll i=2;i<=n;i++){
        printf(" %lld",dis[i]);
    }
    printf("
");
    return 0;
}

原文地址:https://www.cnblogs.com/liuchanglc/p/12963991.html