[最短路]飞行
题目描述
WFYZ的校园很大,这里生活着很多生物,比如住在钟楼上的的鸽子,其中鸽子冉冉和她的妹妹凝凝白天在不同的地方吃虫,而在晚上她们都回到钟楼休息。她俩是两只懒鸟,于是提出了一个计划,尽量减少她们在飞行时花费的总能量。
当从一个区域飞到邻近区域时,冉冉花费R个能量单位,凝凝花费S个能量单位。然而,如果冉冉和凝凝在同一个区域时,冉冉可以背着凝凝飞,而只消耗P个能量单位(其中P可能远远小于R + S)。如果P非常小,最节能的解决方案可能是冉冉和凝凝前往一个区域,然后冉冉背着凝凝飞回钟楼。当然,如果P很大,那么冉冉和凝凝可能各自飞。
给定R,S和P以及校园的布局,请计算冉冉和凝凝到达谷仓所需的最低能量。
当从一个区域飞到邻近区域时,冉冉花费R个能量单位,凝凝花费S个能量单位。然而,如果冉冉和凝凝在同一个区域时,冉冉可以背着凝凝飞,而只消耗P个能量单位(其中P可能远远小于R + S)。如果P非常小,最节能的解决方案可能是冉冉和凝凝前往一个区域,然后冉冉背着凝凝飞回钟楼。当然,如果P很大,那么冉冉和凝凝可能各自飞。
给定R,S和P以及校园的布局,请计算冉冉和凝凝到达谷仓所需的最低能量。
输入
第一行输入包含正整数R,S,P,N和M. (R,S,P,N,M<=40,000)。R,S和P如上所述。 N是校园中的区域数(编号为1..N,其中N> = 3),有M条飞行线路。冉冉和凝凝分别从1区和2区开始。钟楼在N区.
以下输入M行,代表两个区域的有飞行路线。连接是双向的。总是可以沿着一系列这样的连接从场1到场N,场2到场N。
以下输入M行,代表两个区域的有飞行路线。连接是双向的。总是可以沿着一系列这样的连接从场1到场N,场2到场N。
输出
一个整数,冉冉和凝凝集体到达钟楼需要花费的最小能量。
样例输入
4 4 5 8 8
1 4
2 3
3 4
4 7
2 5
5 6
6 8
7 8
样例输出
22
提示
在例子中,冉冉从1到4,凝凝从2到3到4,然后,他们一起旅行从4到7到8。
【数据规模与约定】
对于20%的数据,1≤N≤500,1≤M≤2000。
对于100%的数据,1≤N≤40000,1≤M≤40000。
思路:
跑三遍最短路,分别是两个人(啊,两只鸽子)分别飞到钟楼的花费,还有就是从钟楼到各个区域的最短路,然后枚举会合点
1 #include <iostream> 2 #include <bits/stdc++.h> 3 using namespace std; 4 typedef long long ll; 5 const int maxn = 4e4+50; 6 int sum=0; 7 int tot,r,s,p,n,m; 8 int head[maxn*2],ver[maxn*2],edge[maxn*2],Next[maxn*2],d[maxn*2]; 9 bool v[maxn*2]; 10 int len1[maxn],len2[maxn],len3[maxn]; 11 queue<int> q; 12 void add(int x,int y,int z) 13 { 14 ver[++tot]=y; 15 edge[tot]=z; 16 Next[tot]=head[x]; 17 head[x]=tot; 18 } 19 void spfa(int t) 20 { 21 memset(d,0x3f,sizeof(d)); 22 memset(v,0,sizeof(v)); 23 d[t]=0; 24 v[t]=1; 25 q.push(t); 26 while(q.size()) 27 { 28 int x=q.front(); 29 q.pop(); 30 v[x]=0; 31 for(int i=head[x];i;i=Next[i]) 32 { 33 int y=ver[i],z=edge[i]; 34 if(d[y]>d[x]+z) 35 { 36 d[y]=d[x]+z; 37 if(!v[y]) 38 { 39 q.push(y),v[y]=1; 40 } 41 } 42 } 43 } 44 } 45 int main() 46 { 47 scanf("%d%d%d%d%d",&r,&s,&p,&n,&m); 48 for(register int i=1;i<=m;i++) 49 { 50 int x,y; 51 scanf("%d%d",&x,&y); 52 add(x,y,1); 53 add(y,x,1); 54 } 55 spfa(1); 56 for(register int i=1;i<=n;i++) 57 { 58 len1[i]=d[i]; 59 } 60 int t1=d[n]; 61 spfa(2); 62 for(register int i=1;i<=n;i++) 63 { 64 len2[i]=d[i]; 65 } 66 int t2=d[n]; 67 int res=r*t1+s*t2; 68 spfa(n); 69 for(register int i=1;i<=n;i++) 70 { 71 len3[i]=d[i]; 72 } 73 for(register int i=1;i<=n;i++) 74 { 75 int temp1=r*len1[i]+s*len2[i]; 76 int temp2=p*len3[i]; 77 res=min(res,temp1+temp2); 78 } 79 printf("%d\n",res); 80 //cout << "Hello world!" << endl; 81 return 0; 82 }