P3110 [USACO14DEC]馱運Piggy Back-最短路,spfa
阿新 • • 發佈:2018-12-12
Bessie 和 Elsie在不同的區域放牧,他們希望花費最小的能量返回穀倉。從一個區域走到一個相連區域,Bessie要花費B單位的能量,Elsie要花費E單位的能量。
如果某次他們兩走到同一個區域,Bessie 可以揹著 Elsie走路,花費P單位的能量走到另外一個相連的區域。當然,存在P>B+E的情況。
相遇後,他們可以一直揹著走,也可以獨立分開。
Bessie和Elsie分別從1和2出發到n,如果某一點會相遇,可以選擇剩下的路兩個人一起走或者分開走。
因為只有一次相遇且不會一起走然後又分開,這樣就對1,2,n三個點各跑一次最短路
最後列舉每一個點(相遇點)
ans=min(dis_b[i]*b+dis_e[i]*e+dis_n[i]*p);
相遇前b走過的路程*b+相遇前e走過的路程*e+一起走的路程*p;
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int maxn = 8e4+3; int dis_b[maxn],dis_e[maxn],dis_n[maxn],head[maxn]; bool vis[maxn]; int cnt,b,e,p,n,m,ans=2147483647; const int INF = 2147483647; queue<int> q; struct node { int next,to; }E[maxn*10]; void add(int x,int y) { E[++cnt].next=head[x]; E[cnt].to=y; head[x]=cnt; } void spfa(int s,int *dis) { memset(vis,0,sizeof(vis)); fill(dis+1, dis+1+n, INF); dis[s]=0; vis[s]=true; q.push(s); while(!q.empty()){ int now=q.front();q.pop();vis[now]=false; for(int i=head[now];i;i=E[i].next){ int to=E[i].to; if(dis[to]>dis[now]+1){ dis[to]=dis[now]+1; if(!vis[to]){ q.push(to); vis[to]=true; } } } } } int main() { scanf("%d%d%d%d%d",&b,&e,&p,&n,&m); for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); add(x,y);add(y,x); } spfa(1,dis_b);spfa(2,dis_e);spfa(n,dis_n); for(int i=1;i<=n;i++){ ans=min(ans,dis_b[i]*b+dis_e[i]*e+dis_n[i]*p); } printf("%d",ans); return 0; }