Educational Codeforces Round 38 (Rated for Div. 2) D_Buy a Ticket_加源点Dijkstra

题意

  一国家由 n 个城市构成,城市之间有若干双向通路。一乐队在每个城市举办一场演出, 每次演出的票价不同。每个城市中的人,如果在自己城市看演出,只需要花票钱。否则还要加上往返路费。问对于每个城市来说,里面的人看到演出的最小票价是多少。

思路

  暴力做法 floyd 加 枚举。妥妥的超时(点和边上限 1e5)。
  添加一个源点,到其他点的距离等于那些点的点权。则问题转化成了求其他点到这个点的距离,同时巧妙地把点权转化为边权。这样就可以用dijkstra算法求解单源最短路。

链接

http://codeforces.com/contest/938/problem/D

代码

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

const LL maxn = 2e5 + 10;

struct edge{
    LL to;
    LL cost;
    edge(){}
    edge(LL to, LL cost): to(to), cost(cost){}
    bool operator < (edge a) const{
        if(cost != a.cost) return cost > a.cost;
        return to < a.to;
    }
};

LL n, m;
vector<edge> G[maxn];
LL dis[maxn];
bool vis[maxn];

void solve(){
    memset(dis, -1, sizeof dis);
    dis[0] = 0;
    priority_queue<edge> qu;
    qu.push(edge(0, 0));

    while(!qu.empty()){
        edge d = qu.top();
        qu.pop();

        if(d.cost != dis[d.to]) continue;

        vis[d.to] = true;

        for(LL i = 0; i < G[d.to].size(); i++){
            edge t = G[d.to][i];

            if(!vis[t.to] && (dis[t.to] == -1 || dis[t.to] > d.cost + t.cost)){
                dis[t.to] = d.cost + t.cost;
                qu.push(edge(t.to, dis[t.to]));
            }
        }
    }
}

int main(){
    scanf("%I64d %I64d", &n, &m);
    for(LL i = 1; i <= m; i++){
        LL a, b, c;
        scanf("%I64d %I64d %I64d", &a, &b, &c);
        c <<= 1;
        G[a].push_back(edge(b, c));
        G[b].push_back(edge(a, c));
    }
    for(LL i = 1; i <= n; i++){
        LL x;
        scanf("%I64d", &x);
        G[i].push_back(edge(0, x));
        G[0].push_back(edge(i, x));
    }

    solve();

    for(LL i = 1; i <= n; i++){
        printf("%I64d ", dis[i]);
    }
    puts("");

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值