题意:n个城市,m条路,每条路都有自己的花费,每个城市看演唱会也有自己的花费,问从每一个城市到另一个城市(或就在自己城市)看演唱会的最小花费
题解:迪杰斯特拉,跑多源(每个源有权值)最短路。和一般的跑法不一样,要先给每个dis[]赋值成源的权值然后扔进dij里面。
#include <cstdio> #include <algorithm> #include <vector> #include <cstring> #define se second #define fi first #define ll long long const double Pi=3.14159265; const int N=2e5+5; const ull base=163; using namespace std; int head[N]; bool vis[N]; ll dis[N]; int tot=1; int n,m; struct node{ int nx; int to; ll len; }e[2*N]; priority_queue<Pli,vector<Pli>,greater<Pli> >q; void add(int u,int v,ll w){ e[tot].to=v; e[tot].len=w; e[tot].nx=head[u]; head[u]=tot++; } void dij(){ while(!q.empty()){ Pli now=q.top();q.pop(); ll p=now.fi; int u=now.se; if(dis[u]<p)continue; for(int i=head[u];i;i=e[i].nx){ int v=e[i].to; if(dis[v]>dis[u]+e[i].len){ dis[v]=dis[u]+e[i].len; q.push(Pli(dis[v],v)); } } } } int main(){ scanf("%d %d",&n,&m); while(m--){ int u,v; ll w; scanf("%d %d %I64d",&u,&v,&w); add(u,v,2*w); add(v,u,2*w); } for(int i=1;i<=n;i++){ ll t; scanf("%lld",&t); dis[i]=t; q.push(Pli(t,i)); } dij(); for(int i=1;i<=n;i++)printf("%lld ",dis[i]); return 0; }