正题
题目大意
nnn个点mmm条边的无向图,每个点有门票费,对于每个点求一个点使得去那里看完赛艇并回来消耗的时间最小。
解题思路
因为是无向图,所以去和回是同一条路,把每个点作为起点将门票费压入然后跑最短路。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const ll N=2e5+10;
struct node{ll x,w;
};
struct edge_node{ll to,next,w;
}a[N*2];
ll n,m,f[N],ls[N],tot;
bool v[N];
priority_queue<node> q;
bool operator<(node x,node y)
{return x.w>y.w;}
void addl(ll x,ll y,ll w)
{a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;
}
void dij()
{while(!q.empty()){ll x=q.top().x;q.pop();if(v[x]) continue;v[x]=1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(f[x]+a[i].w<f[y]){f[y]=f[x]+a[i].w;if(!v[y])q.push((node){y,f[y]});}}}
}
int main()
{scanf("%lld%lld",&n,&m);for(ll i=1;i<=m;i++){ll x,y,w;scanf("%lld%lld%lld",&x,&y,&w);addl(x,y,w*2);addl(y,x,w*2);}for(ll i=1;i<=n;i++){scanf("%lld",&f[i]);q.push((node){i,f[i]});}dij();for(ll i=1;i<=n;i++)printf("%lld ",f[i]);
}