【问题描述】
Bessie 和她的姐姐 Elsie 在不同的田块吃草, 晚上她们都返回牛棚休息。 作为聪明的奶
牛, 她们想设计一个方案使得步行消耗的能量最少。
Bessie 从一个田块到相邻的田块要耗费 B 个单位的能量, Elsie 从一个田块到相邻的田块
要耗费 E 个单位的能量。 然而当 Bessie 和 Elsie 处于同一个田块时, Bessie 用背驮着 Elsie 一
起走, 从一个田块到相邻的田块要耗费 P 个单位的能量。 如果 P 小于 B+E,则被认为是比较
适用的; 如果 P 非常小, 那么最佳的方案就是尽快使得 Bessie 和 Elsie 在某一田块相遇; 当
然如果 P 非常大, 那么则尽可能使得 Bessie 和 Elsie 分开走。 另一方面, 她们对“背驮式”
很不高兴, 她们不明白为什么这种猪用来驮运的方式会被认为是优秀的方法。
给出 B,E 和 P,帮助她们姐俩找出从牧场到牛棚的花费能量最小的方案。
【输入格式】
第一行包含 5 个正整数 B,E,P,N 和 M。 N 是牧场中田块的数量(分别编号为 1..N),M 表示田块之间通路条数.Bessie 和 Elsie 一开始分别位于 1 和 2,牛棚位于 N.接下来 M 行, 每行一对整数 U 和 V, 分别表示两个田块之间有通路。 通路连接是双向的, 可以从 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
【样例解释】
样例中, Bessie 从 1 到 4, Elsie 从 2 到 3 到 4.然后她们一起从 4 到 7 到 8.
【数据规模】
对于 40%的数据: 3≤N,M≤6,000;
对于 100%的数据: 3≤B,E,P,N,M≤40,000; 1≤U, V≤N; 且 U≠V;
题面貌似十分复杂,但细想并不是很难。只要枚举每一个点,取min,将Bessie,Elsie
走到这个点的最小能量,加上从这个点到终点的能量。
我们可以用广搜(SPFA),就可以求出1, 2,n到每个点的能量。
//d1[i]表示1到i的距离
//d2[i]表示2到i的距离
//d3[i]表示n到i的距离
for(int i=1;i<=n;i++)
ans=min(ans,d1[i]+d2[i]+d3[i]);
这就是核心伪代码。
表示不想写void,直接程序里写了广搜CtrC CtrV
#include<bits/stdc++.h>
#include<vector>
#define zz 2e9
using namespace std;
long long i,j,k,n,m,tot,ans,u,p,v,e,b,tail,head,t,h,ta,he;
long long d1[40005],d2[40005],d3[40005],q[100005],q1[100005];
vector<long long> f[40005];
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';
return x;
}
int minn(int a,int b){return a<b?a:b;}
int main()
{
b=read(),e=read(),p=read(),n=read(),m=read();head=0,tail=0;
for(int i=1;i<=m;i++){
int x=read(),y=read();
f[x].push_back(y);
f[y].push_back(x);
}
for(int i=1;i<=n;i++) d1[i]=d2[i]=d3[i]=zz;
for(int i=0;i<f[1].size();i++){
q[++tail]=f[1][i];d1[f[1][i]]=b;
}
d1[1]=0,d2[2]=0,d3[n]=0;
while(head<tail){
head++;
for(int i=0;i<f[q[head]].size();i++){
if(d1[q[head]]+b<d1[f[q[head]][i]]){
d1[f[q[head]][i]]=d1[q[head]]+b;
q[++tail]=f[q[head]][i];
}
}
}
h=0;t=0;
for(int i=0;i<f[2].size();i++){
q[++t]=f[2][i];d2[f[2][i]]=e;
}
while(h<t){
h++;
for(int i=0;i<f[q[h]].size();i++){
if(d2[q[h]]+e<d2[f[q[h]][i]]){
d2[f[q[h]][i]]=d2[q[h]]+e;
q[++t]=f[q[h]][i];
}
}
}
he=0;ta=0;
d3[n]=0;
for(int i=0;i<f[n].size();i++){
q1[++ta]=f[n][i];d3[f[n][i]]=p;
}
while(he<ta){
he++;
for(int i=0;i<f[q1[he]].size();i++){
if(d3[q1[he]]+p<d3[f[q1[he]][i]]){
d3[f[q1[he]][i]]=d3[q1[he]]+p;
q1[++ta]=f[q1[he]][i];
}
}
}
d1[1]=0,d2[2]=0,d3[n]=0;
ans=2147483647;
for(int i=1;i<=n;i++){
ans=minn(ans,d1[i]+d2[i]+d3[i]);
}
printf("%d",ans);
return 0;
}