赛艇表演
时间限制: 3 Sec 内存限制: 256 MB题目描述
小明去某个地区观看赛艇比赛,这个地区共有n个城市和m条道路,每个城市都有赛艇比赛,在第i个城市观看赛艇表演的价钱为ai, 去其他城市观看也需要支付赛艇表演的价格。任意两个城市之间通过一条公路连接,并且道路是双向通行的, 观看赛艇比赛时经过的每一条道路都要支付一定的过路费,观看完比赛返回家时经过的每一条道路也要支付过路费。
对于每个城市u,你需要为小明确定一个城市v,使得从u出发,前往v看赛艇表演,再从v回到u,u可以等于v,要求花费的总金额尽量的少。请根据题目给出的数据输出总金额。
对于每个城市u,你需要为小明确定一个城市v,使得从u出发,前往v看赛艇表演,再从v回到u,u可以等于v,要求花费的总金额尽量的少。请根据题目给出的数据输出总金额。
输入
第一行两个正整数n和m。
接下来m行,每行三个正整数u,v,w,表示有一条双向道路连接u和v,且每经过一次的过路费是w。 接下来一行n个数,第i个数表示在第i个城市观看赛艇表演的价钱。
接下来m行,每行三个正整数u,v,w,表示有一条双向道路连接u和v,且每经过一次的过路费是w。 接下来一行n个数,第i个数表示在第i个城市观看赛艇表演的价钱。
输出
输出一行n个数,第i个数表示从第i个城市出发至少要花多少钱
样例输入 Copy
4 2
1 2 4
2 3 7
6 20 1 25
样例输出 Copy
6 14 1 25
提示
对于前30%的数据,n<=10,m<=20。
对于前50%的数据,n<=100,m<=500。
对于前70%的数据,n<=1500,m<=2000。
对于前85%的数据,图的结构以某种方式随机生成。
对于100%的数据,n<=2e5,m<=2e5,过路费和门票钱都在[1,1e12]内。
对于前50%的数据,n<=100,m<=500。
对于前70%的数据,n<=1500,m<=2000。
对于前85%的数据,图的结构以某种方式随机生成。
对于100%的数据,n<=2e5,m<=2e5,过路费和门票钱都在[1,1e12]内。
首先,如果暴力找每一个点的最短路一定T
所以,考虑将结点权值加在边上 ,先造一个超级原点,使每个点到原点的都有一条双向边,且边权是结点权值,其次每条边的边权是来回两次,边权是2*w;
如图建图;
代码如下
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=2e5+50; 4 typedef long long ll; 5 struct ss 6 { 7 int u,v,next; 8 ll w; 9 }edg[N*5]; 10 int sumedg,head[N]; 11 void addedg(int u,int v,ll w) 12 { 13 edg[sumedg]=(ss){u,v,head[u],w}; 14 head[u]=sumedg++; 15 } 16 ll n,m,value[N]; 17 ll dis[N]; 18 bool vis[N]; 19 void spfa() 20 { 21 queue<int>q; 22 memset(vis,0,sizeof(vis)); 23 for(int i=0;i<n+10;i++) dis[i]=LONG_LONG_MAX; 24 q.push(0); 25 vis[0]=1; 26 dis[0]=0; 27 while(!q.empty()) 28 { 29 int now=q.front();q.pop();vis[now]=0; 30 for(int i=head[now];i!=-1;i=edg[i].next) 31 { 32 int v=edg[i].v; 33 long long w=edg[i].w; 34 35 if(dis[v]>dis[now]+w) 36 { 37 dis[v]=dis[now]+w; 38 if(!vis[v]) 39 { 40 q.push(v); 41 vis[v]=1; 42 } 43 } 44 } 45 } 46 47 } 48 int main() 49 { 50 scanf("%lld%lld",&n,&m); 51 memset(dis,0,sizeof(dis)); 52 for(ll i=0;i<n+10;i++) head[i]=-1; 53 for(ll i=0;i<m;i++) 54 { 55 int u,v;ll w; 56 scanf("%d%d%lld",&u,&v,&w); 57 addedg(u,v,w*2); 58 addedg(v,u,w*2); 59 } 60 for(ll i=1;i<=n;i++) 61 { 62 scanf("%lld",&value[i]); 63 addedg(0,i,value[i]); 64 addedg(i,0,value[i]); 65 } 66 spfa(); 67 for(ll i=1;i<=n;i++) 68 { 69 printf("%lld%c",dis[i],i==n?' ':' '); 70 } 71 return 0; 72 }