[USACO14DEC]驮运Piggy Back

题目描述

Bessie 和 Elsie在不同的区域放牧,他们希望花费最小的能量返回谷仓。从一个区域走到一个相连区域,Bessie要花费B单位的能量,Elsie要花费E单位的能量。

如果某次他们两走到同一个区域,Bessie 可以背着 Elsie走路,花费P单位的能量走到另外一个相连的区域,满足P<B+E。

相遇后,他们可以一直背着走,也可以独立分开。

输入输出样例

输入样例#1:
4 4 5 8 8 
1 4 
2 3 
3 4 
4 7 
2 5 
5 6 
6 8 
7 8 
输出样例#1:
22 
3次SPFA就可以了
可以知道,他们在相遇后就不分开了,因为背到终点一定最优
dist1[x]表示从1出发到x最短路
dist2同理

dist3表示到n的最短路
ans=min(dist1[x]*b+dist2[x]*e+dist3[x]*p)
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 struct Messi
 7 {
 8     int next,to;
 9 }edge[80001];
10 int head[40001],num,n,m,f[40001][4],ans,dist[40001],vis[40001];
11 void add(int u,int v)
12 {
13     num++;
14     edge[num].next=head[u];
15      head[u]=num;
16      edge[num].to=v;
17 }
18 void bfs(int x)
19 {int q[100001]={0},h,t,u,v,i;
20     q[1]=x;h=0;t=1;
21      while (h<t)
22      {
23          h++;
24           u=q[h];
25           vis[u]=0;
26            for (i=head[u];i;i=edge[i].next)
27            {
28                int v=edge[i].to;
29                 if (dist[u]+1<dist[v])
30                 {
31                     dist[v]=dist[u]+1;
32                     if (vis[v]==0)
33                      t++,q[t]=v;
34              }
35            }
36      }
37 //     cout<<x<<' ';
38 //    for (i=1;i<=n;i++)
39 //    cout<<dist[i]<<' ';
40 //    cout<<endl;
41 }
42 int main()
43 {int b,e,p,i,u,v;
44     cin>>b>>e>>p>>n>>m;
45      for (i=1;i<=m;i++)
46       {
47           scanf("%d%d",&u,&v);
48           add(u,v);
49           add(v,u);
50       }
51       memset(dist,127/3,sizeof(dist));dist[1]=0;memset(vis,0,sizeof(vis));
52      bfs(1);
53       for (i=1;i<=n;i++)
54         f[i][1]=dist[i];
55        memset(dist,127/3,sizeof(dist));dist[2]=0;memset(vis,0,sizeof(vis));
56      bfs(2);
57      for (i=1;i<=n;i++)
58         f[i][2]=dist[i];
59      memset(dist,127/3,sizeof(dist));dist[n]=0;memset(vis,0,sizeof(vis));
60      bfs(n);
61      for (i=1;i<=n;i++)
62         f[i][3]=dist[i];
63     ans=2e9;
64     for (i=1;i<=n;i++)
65      ans=min(ans,f[i][1]*b+f[i][2]*e+f[i][3]*p);
66      cout<<ans;
67 }

 

转载于:https://www.cnblogs.com/Y-E-T-I/p/7365587.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值