码迷,mamicode.com
首页 > 其他好文 > 详细

最短路 || Codeforces 938D Buy a Ticket

时间:2018-08-30 00:07:54      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:name   uil   题意   std   void   using   双向   codeforce   head   

题意:从城市u到v(双向)要花w钱,每个城市看演唱会要花不同的门票钱,求每个城市的人要看一场演唱会花费最少多少(可以在这个城市看,也可以坐车到别的城市看,然后再坐车回来)

思路:本来以为是多源。。实际上是单源

考虑dij的松弛操作,是每次取队列里值最小的点u(队首),看它能拓展到的点v,如果经过u到v的代价比当前到v的代价低,那么就更新v

这里也同理,只不过代价是路程*2加上在v看演唱会的钱

嗯。。神奇的dij

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
#define SZ 411000
int head[SZ],nxt[SZ],tot = 0;
struct edge
{
    int t;
    LL d;
}l[SZ];
void build(int f,int t,LL d)
{
    l[++ tot] = (edge){t,d};
    nxt[tot] = head[f];
    head[f] = tot;
}
struct node
{
    int u;
    LL d;
};
bool vis[SZ];
LL dist[SZ];
priority_queue<node> q;
bool operator < (node a, node b) {return a.d > b.d; }
int main()
{
    int n, m, v, u;
    LL w;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < m; i++)
    {
        scanf("%d %d %lld", &v, &u, &w);
        build(v, u, w);
        build(u, v, w);
    }
    for(int i = 1; i <= n; i++) scanf("%lld", &dist[i]), q.push((node){i, dist[i]} );
    while(q.size())
    {
        int u = q.top().u;
        q.pop();
        if(vis[u]) continue;
        vis[u] = 1;
        for(int i = head[u]; i;i = nxt[i])
        {
            int v = l[i].t;
            if(dist[v] > dist[u] + 2 * l[i].d)
            {
                dist[v] = dist[u] + 2 * l[i].d;
                q.push((node){v, dist[v]});
            }
        }
    }
    for(int i = 1; i <= n; i++)
    {
        if(i != 1) printf(" ");
        printf("%lld", dist[i]);
    }
    printf("\n");
    return 0;
}

 

最短路 || Codeforces 938D Buy a Ticket

标签:name   uil   题意   std   void   using   双向   codeforce   head   

原文地址:https://www.cnblogs.com/pinkglightning/p/9557478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!