Piggy Back

来源:互联网 发布:sql sever外键约束 编辑:程序博客网 时间:2024/06/05 07:01

问题描述
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 2e9using 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;}