Buy a Ticket(超級源點+Dij)

Buy a Ticket(超級源點+Dij)

Describe

Musicians of a popular band "Flayer" have announced that they are going to "make their exit" with a world tour. Of course, they will visit Berland as well.ios

There are n cities in Berland. People can travel between cities using two-directional train routes; there are exactly m routes, i-th route can be used to go from city v i to city u i (and from u i to v i), and it costs w i coins to use this route.c++

Each city will be visited by "Flayer", and the cost of the concert ticket in i-th city is a i coins.ide

You have friends in every city of Berland, and they, knowing about your programming skills, asked you to calculate the minimum possible number of coins they have to pay to visit the concert. For every city i you have to compute the minimum number of coins a person from city i has to spend to travel to some city j (or possibly stay in city i), attend a concert there, and return to city i (if j ≠ i).this

Formally, for every img you have to calculate img, where d(i, j) is the minimum number of coins you have to spend to travel from city i to city j. If there is no way to reach city j from city i, then we consider d(i, j) to be infinitely large.spa

Input

The first line contains two integers n and m (2 ≤ n ≤ 2·105, 1 ≤ m ≤ 2·105).code

Then m lines follow, i-th contains three integers v i, u i and w i (1 ≤ v i, u i ≤ n, v i ≠ u i, 1 ≤ w i ≤ 1012) denoting i-th train route. There are no multiple train routes connecting the same pair of cities, that is, for each (v, u) neither extra (v, u) nor (u, v) present in input.orm

The next line contains n integers a 1, a 2, ... a k (1 ≤ a i ≤ 1012) — price to attend the concert in i-th city.blog

Output

Print n integers. i-th of them must be equal to the minimum number of coins a person from city i has to spend to travel to some city j (or possibly stay in city i), attend a concert there, and return to city i (if j ≠ i).three

Translate

流行樂隊「Flayer」將在n個城市開演唱會 這n個城市的人都想去聽演唱會 每一個城市的票價不一樣 因而這些人就想是否能去其餘城市聽演唱會更便宜(去要路費的)ip

輸入格式: 第一行包含兩個整數n和m

接下來m行 每行三個數 u v k 表示u城市到v城市要k元

接下來n個數 表每一個城市的票價

Input

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

Output

6 14 1 25

Input

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

Output

12 10 12

Solution

​ 這道題代碼不難,主要是思路很巧妙,須要建一個超級源點,咱們能夠讓每一個節點上的人從這個超級源點出發,這個超級源點與每一個節點都連有一條邊,邊權是該點的值,這樣由源點出發到每一個節點 i 最短路就至關因而從節點 i 出發到花費最少的一個點並參加音樂會所花費的最小值,固然尚未回到 i ,怎樣才能求算上回到 i 的最小值呢,咱們將 n 個點之間的邊的邊權乘 2 跑最短路就好了。

​ 所以處理方法爲:

​ m 個邊,邊權*2存邊;個點權做爲一個邊權與超級源點建邊,從超級源點跑單源最短路,輸出 1~n 每一個節點的最短路便可。

​ 注意:

​ 所有都是雙向邊,邊數要搞對,maxn*4,別忘了超級源點也和每一個邊連有雙向邊。

Code

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const ll Inf=1e13;
ll dis[maxn];
int n,m,cnt,head[maxn];
bool vis[maxn];
struct Edge{int to,next;ll val;}e[800000+5];
void Add(int x,int y,ll z){
	e[++cnt].to=y;
	e[cnt].val=z;
	e[cnt].next=head[x];
	head[x]=cnt;
}
void Dij(int S){
	priority_queue<pair<ll,int> > q;
	for(int i=1;i<=n;++i)dis[i]=Inf;
	dis[S]=0;q.push(make_pair(0,S));
	while(!q.empty()){
		int x=q.top().second;q.pop();
		if(vis[x])continue;
		vis[x]=1;
		for(int i=head[x];i;i=e[i].next){
			int v=e[i].to;ll w=e[i].val;
			if(!vis[v]&&dis[v]>dis[x]+w){
				dis[v]=dis[x]+w;
				q.push(make_pair(-dis[v],v));
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);
	int x,y;ll z;
	for(int i=1;i<=m;++i){
		scanf("%d%d%lld",&x,&y,&z);
		Add(x,y,(z<<1));Add(y,x,(z<<1));
	}
	for(int i=1;i<=n;++i){
		scanf("%lld",&z);
		Add(i,n+1,z);Add(n+1,i,z);
	}
	Dij(n+1);
	for(int i=1;i<=n;++i)
		printf("%lld ",dis[i]);
	return 0;
}
相關文章
相關標籤/搜索