[最短路]飞行

题目描述

WFYZ的校园很大,这里生活着很多生物,比如住在钟楼上的的鸽子,其中鸽子冉冉和她的妹妹凝凝白天在不同的地方吃虫,而在晚上她们都回到钟楼休息。她俩是两只懒鸟,于是提出了一个计划,尽量减少她们在飞行时花费的总能量。

当从一个区域飞到邻近区域时,冉冉花费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。
 

 

输出

一个整数,冉冉和凝凝集体到达钟楼需要花费的最小能量。

 

样例输入

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 }
View Code

 

posted @ 2019-01-22 16:24  听风不成泣  阅读(177)  评论(0编辑  收藏  举报