题意:
有 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;
}