【网络流24题】 No.15 汽车加油行驶问题 (分层图最短路i)
【题意】
问题描述:
给定一个 N*N 的方形网格,设其左上角为起点◎, 坐标为( 1, 1), X 轴向右为正, Y
轴向下为正, 每个方格边长为 1, 如图所示。 一辆汽车从起点◎出发驶向右下角终点▲,其
坐标为( N, N)。 在若干个网格交叉点处, 设置了油库, 可供汽车在行驶途中加油。 汽车在
行驶过程中应遵守如下规则:
(1)汽车只能沿网格边行驶,装满油后能行驶 K 条网格边。出发时汽车已装满油, 在起
点与终点处不设油库。
(2)汽车经过一条网格边时, 若其 X 坐标或 Y 坐标减小, 则应付费用 B, 否则免付费用。
(3)汽车在行驶过程中遇油库则应加满油并付加油费用 A。
(4)在需要时可在网格点处增设油库,并付增设油库费用 C(不含加油费用 A)。
(5)(1)~(4)中的各数 N、 K、 A、 B、 C 均为正整数, 且满足约束: 2 <=N <= 100, 2 <= K <= 10。
设计一个算法, 求出汽车从起点出发到达终点的一条所付费用最少的行驶路线。
输入文件示例
input.txt
9 3 2 3 6
0 0 0 0 1 0 0 0 0
0 0 0 1 0 1 1 0 0
1 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 1
1 0 0 1 0 0 1 0 0
0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 1
1 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0输出文件示例
output.txt
12
【分析】
每天智障24小时again。。
我在纠结要是建了加油站 又走回那个点怎么破。。。
傻逼才走回以前那个点。。。
对,傻逼就是我。。
k很小,直接表示在状态里面,那么。。分层图最短路。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 using namespace std; 9 #define Maxn 110 10 #define INF 0xfffffff 11 12 int n,k,A,B,C; 13 bool g[Maxn][Maxn]; 14 15 int mymin(int x,int y) {return x<y?x:y;} 16 17 void init() 18 { 19 scanf("%d%d%d%d%d",&n,&k,&A,&B,&C); 20 for(int i=1;i<=n;i++) 21 for(int j=1;j<=n;j++) 22 { 23 int x; 24 scanf("%d",&x); 25 if(x==1) g[i][j]=1; 26 else g[i][j]=0; 27 } 28 } 29 30 int bx[6]={0,1,0,-1,0}, 31 by[6]={0,0,1,0,-1}, 32 cs[6]; 33 34 struct node 35 { 36 int x,y,z; 37 }; 38 int dis[Maxn][Maxn][15]; 39 bool inq[Maxn][Maxn][15]; 40 queue<node > q; 41 void spfa() 42 { 43 while(!q.empty()) q.pop(); 44 memset(dis,63,sizeof(dis)); 45 memset(inq,0,sizeof(inq)); 46 node ft; 47 int ans=INF; 48 ft.x=1,ft.y=1,ft.z=k; 49 q.push(ft);dis[1][1][k]=0;inq[1][1][k]=1; 50 cs[1]=cs[2]=0;cs[3]=cs[4]=B; 51 while(!q.empty()) 52 { 53 node now=q.front(); 54 int x=now.x,y=now.y,z=now.z; 55 for(int i=1;i<=4;i++) if(x+bx[i]>=1&&x+bx[i]<=n&&y+by[i]>=1&&y+by[i]<=n) 56 { 57 node nn; 58 int c=cs[i]+dis[x][y][z]; 59 nn.x=x+bx[i];nn.y=y+by[i];nn.z=z-1; 60 if(nn.x==n&&nn.y==n) {ans=mymin(ans,c);continue;} 61 if(g[nn.x][nn.y]) nn.z=k,c+=A; 62 if(nn.z==0) nn.z=k,c+=C+A; 63 if(c<dis[nn.x][nn.y][nn.z]) 64 { 65 dis[nn.x][nn.y][nn.z]=c; 66 if(!inq[nn.x][nn.y][nn.z]) 67 { 68 q.push(nn); 69 inq[nn.x][nn.y][nn.z]=1; 70 } 71 } 72 } 73 q.pop();inq[x][y][z]=0; 74 } 75 printf("%d\n",ans); 76 } 77 78 int main() 79 { 80 init(); 81 spfa(); 82 return 0; 83 }
还挺好打,只是像我这种不用脑子大代码的就要调试很久。。
2016-11-06 19:45:09