题目描述
Bessie 和 Elsie在不同的区域放牧,他们希望花费最小的能量返回谷仓。从一个区域走到一个相连区域,Bessie要花费B单位的能量,Elsie要花费E单位的能量。
如果某次他们两走到同一个区域,Bessie 可以背着 Elsie走路,花费P单位的能量走到另外一个相连的区域,满足P<B+E。
相遇后,他们可以一直背着走,也可以独立分开。
输入输出样例
输入样例#1:
4 4 5 8 8 1 4 2 3 3 4 4 7 2 5 5 6 6 8 7 8
输出样例#1:
22
3次SPFA就可以了
可以知道,他们在相遇后就不分开了,因为背到终点一定最优
dist1[x]表示从1出发到x最短路
dist2同理
dist3表示到n的最短路
ans=min(dist1[x]*b+dist2[x]*e+dist3[x]*p)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Messi 7 { 8 int next,to; 9 }edge[80001]; 10 int head[40001],num,n,m,f[40001][4],ans,dist[40001],vis[40001]; 11 void add(int u,int v) 12 { 13 num++; 14 edge[num].next=head[u]; 15 head[u]=num; 16 edge[num].to=v; 17 } 18 void bfs(int x) 19 {int q[100001]={0},h,t,u,v,i; 20 q[1]=x;h=0;t=1; 21 while (h<t) 22 { 23 h++; 24 u=q[h]; 25 vis[u]=0; 26 for (i=head[u];i;i=edge[i].next) 27 { 28 int v=edge[i].to; 29 if (dist[u]+1<dist[v]) 30 { 31 dist[v]=dist[u]+1; 32 if (vis[v]==0) 33 t++,q[t]=v; 34 } 35 } 36 } 37 // cout<<x<<' '; 38 // for (i=1;i<=n;i++) 39 // cout<<dist[i]<<' '; 40 // cout<<endl; 41 } 42 int main() 43 {int b,e,p,i,u,v; 44 cin>>b>>e>>p>>n>>m; 45 for (i=1;i<=m;i++) 46 { 47 scanf("%d%d",&u,&v); 48 add(u,v); 49 add(v,u); 50 } 51 memset(dist,127/3,sizeof(dist));dist[1]=0;memset(vis,0,sizeof(vis)); 52 bfs(1); 53 for (i=1;i<=n;i++) 54 f[i][1]=dist[i]; 55 memset(dist,127/3,sizeof(dist));dist[2]=0;memset(vis,0,sizeof(vis)); 56 bfs(2); 57 for (i=1;i<=n;i++) 58 f[i][2]=dist[i]; 59 memset(dist,127/3,sizeof(dist));dist[n]=0;memset(vis,0,sizeof(vis)); 60 bfs(n); 61 for (i=1;i<=n;i++) 62 f[i][3]=dist[i]; 63 ans=2e9; 64 for (i=1;i<=n;i++) 65 ans=min(ans,f[i][1]*b+f[i][2]*e+f[i][3]*p); 66 cout<<ans; 67 }