Codeforces 938D. Buy a Ticket (Dijkstra)

题意:

n n 个点和 m m 条带权值边,对于每一个点,都会有看电影票的值,而且每一条边都会有边权,问你每一个点看电影票的最小代价是多少?
看电影的代价为:路径上的边权 乘以 2 2 再加上所到的点的看电影票的价值!

样例

input:
4 2
1 2 4
2 3 7
6 20 1 25
output:
6 14 1 25

分析:

建一个“超级原点”,与所有的点建一条边,边的价值为所到的点的电影票价值,并将其他边的权值变成原来的 2 2 倍,这样跑出来的答案其实就是最后的答案了!

代码:

#pragma GCC optimize(2)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <queue>
#include <time.h>
#include <string.h>
#define MAXN 200005
#define ll long long
#define INF 1000000005000
#define P pair<ll,ll>
#define MOD 1000000007
using namespace std;
int n,m;
ll x,y,z,cost[MAXN],mincost[MAXN];
std::vector<P> G[MAXN];
inline ll read()
{
    ll x=0;
    char c=getchar();
    bool flag=0;
    while(c<'0'||c>'9'){if(c=='-')flag=1;   c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?-x:x;
}
void Dijstra()
{
    for(int i=0; i<=n; i++) mincost[i]=INF;
    priority_queue<P,vector<P>,greater<P> > my_que;
    mincost[0]=0;
    my_que.push(P(0,0));
    while(!my_que.empty())
    {
        P p=my_que.top(); my_que.pop();
        int v=p.second;
        if(mincost[v]<p.first) continue;
        for(int i=0; i<(int)G[v].size(); i++)
        {
            if(mincost[G[v][i].first]>mincost[v]+G[v][i].second)
            {
                mincost[G[v][i].first]=mincost[v]+G[v][i].second;
                my_que.push(P(mincost[G[v][i].first],G[v][i].first));
            }
        }
    }
}
int main(int argc, char const *argv[])
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        G[x].push_back(P(y,z*2));
        G[y].push_back(P(x,z*2));
    }
    for(int i=1;i<=n;i++)
        G[0].push_back(P(i,read()));
    Dijstra();
    for(int i=1;i<=n;i++) printf("%lld ",mincost[i]);
    return 0;
}
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/qq_39809664/article/details/79337899
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞