汽车加油行驶(cogs 737)
«问题描述:
给定一个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。
设计一个算法,求出汽车从起点出发到达终点的一条所付费用最少的行驶路线。
«编程任务:
对于给定的交通网格,计算汽车从起点出发到达终点的一条所付费用最少的行驶路线。
«数据输入:
由文件trav.in提供输入数据。文件的第一行是N,K,A,B,C的值。第二行起是一
个N*N 的0-1 方阵,每行N 个值,至N+1 行结束。方阵的第i 行第j 列处的值为1 表示在
网格交叉点(i,j)处设置了一个油库,为0 时表示未设油库。各行相邻两个数以空格分隔。
«结果输出:
程序运行结束时,将最小费用输出到文件trav.out中。
输入文件示例 输出文件示例
trav.in
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
trav.out
12
/*
分层图最短路。
这个题目看上去很难处理,是因为它有很多限制条件,如果我们把这些限制条件去除之后,就变成了单纯求最短路。
至于这些条件,我们可以再跑最短路的时候分类讨论。
如果当前没有油了,就要加油;如果当前有油,就可以前往四周的地方。
然后再做最短路的时候可以加一维,表示当前的油量,多出来的一维可以用分层图最短路来实现。
*/
#include<iostream>
#include<cstdio>
#include<queue>
#define N 1000010
#define inf 1000000000
using namespace std;
int head[N],dis[N],inq[N],map[][],vc[],n,K,A,B,C,S,cnt;
int dx[]={,-,,};
int dy[]={-,,,};
struct node{int v,w,pre;}e[N*];
queue<int> q;
void add(int u,int v,int w){
e[++cnt].v=v;e[cnt].w=w;e[cnt].pre=head[u];head[u]=cnt;
}
int id(int k,int i,int j){return k*n*n+(i-)*n+j;}
void spfa(){
for(int i=;i<=id(K,n,n);i++) dis[i]=inf;
dis[S]=;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();inq[u]=;
for(int i=head[u];i;i=e[i].pre)
if(dis[e[i].v]>dis[u]+e[i].w){
dis[e[i].v]=dis[u]+e[i].w;
if(!inq[e[i].v]){
inq[e[i].v]=;
q.push(e[i].v);
}
}
}
}
int main(){
freopen("trav.in","r",stdin);
freopen("trav.out","w",stdout);
scanf("%d%d%d%d%d",&n,&K,&A,&B,&C);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&map[i][j]);
S=id(K,,);vc[]=C;
for(int k=;k<=K;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
int tmp=id(k,i,j);
if(!k) {add(tmp,id(K,i,j),A+vc[map[i][j]]);continue;}
for(int d=;d<;d++){
int x=i+dx[d],y=j+dy[d];
if(x<||x>n||y<||y>n) continue;
if(d<){
if(map[x][y]) add(tmp,id(K,x,y),A+B);
else add(tmp,id(k-,x,y),B);
}
else {
if(map[x][y]) add(tmp,id(K,x,y),A);
else add(tmp,id(k-,x,y),);
}
}
if(k<K) add(tmp,id(K,i,j),A+vc[map[i][j]]);
}
spfa();
int ans=inf;
for(int i=;i<=K;i++)
ans=min(ans,dis[id(i,n,n)]);
printf("%d",ans);
return ;
}
汽车加油行驶(cogs 737)的更多相关文章
- P4009 汽车加油行驶问题
P4009 汽车加油行驶问题 最短路 清一色的spfa....送上一个堆优化Dijkstra吧(貌似代码还挺短) 顺便说一句,堆优化Dj跑分层图灰常好写 #include<iostream> ...
- 洛谷 P4009 汽车加油行驶问题 解题报告
P4009 汽车加油行驶问题 题目描述 给定一个\(N×N\)的方形网格,设其左上角为起点◎,坐标(1,1) ,\(X\)轴向右为正,\(Y\)轴向下为正,每个方格边长为1 ,如图所示. 一辆汽车从起 ...
- 【题解】【网络流24题】汽车加油行驶问题 [P4009] [Loj6223]
[题解][网络流24题]汽车加油行驶问题 [P4009] [Loj6223] 传送门:汽车加油行驶问题 \([P4009]\) \([Loj6223]\) [题目描述] 给出一个 \(N \times ...
- 【网络流24题】 No.15 汽车加油行驶问题 (分层图最短路i)
[题意] 问题描述:给定一个 N*N 的方形网格,设其左上角为起点◎, 坐标为( 1, 1), X 轴向右为正, Y轴向下为正, 每个方格边长为 1, 如图所示. 一辆汽车从起点◎出发驶向右下角终点▲ ...
- 【刷题】LOJ 6223 「网络流 24 题」汽车加油行驶问题
题目描述 给定一个 \(\text{N}\times \text{N}\) 的方形网格,设其左上角为起点◎,坐标为 \(\text{(1,1)}\) ,\(\text{X}\) 轴向右为正, \(\t ...
- 洛谷P4009 汽车加油行驶问题
题目描述 给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示. 一辆汽车从起点◎出发 ...
- 【洛谷4009】汽车加油行驶问题(SPFA乱搞)
点此看题面 大致题意:给定一个\(N*N\)的方形网格,其中1表示这个格子有油库,0表示这个格子没油库,且汽车加满油可以行驶\(k\)条网格边.如果遇到油库必须加满油并花费\(A\)元,如果\(X\) ...
- 洛谷P4009 汽车加油行驶问题(分层最短路)
传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...
- 洛谷P4009汽车加油行驶问题——网络流24题(最短路)
题目:https://www.luogu.org/problemnew/show/P4009 网络流24题中不是网络流的最短路题: 把每个点拆成各个油量上的点,根据要求连边即可: 注意:点数最大为10 ...
随机推荐
- fopen打开文件失败的问题
fopen打开带中文路径或含中文名称的文件失败. 解决这个问题有两个方法:一是改用_wfopen,这个函数接受两个宽字符类型,函数原型如下: FILE* _wfopen(const wchar_t* ...
- Mysql操作方法类
帮助类: using System; using System.Collections.Generic; using System.Data; using System.Linq; using Sys ...
- jsp引用servlet生成的验证码代码演示
此演示代码主要包括以下三部分:1.checkCode.java:用于生成验证码2.checkCodeServler3.check.jsp 验证 下面是checkCode.java的内容: 复制代码代码 ...
- 一道JS面试题所引发的"血案",透过现象寻本质,再从本质看现象
觉得本人写的不算很烂的话,可以登录关注一下我的GitHub博客,新手写东西写的不好之处,还望见谅,毕竟水平有限,写东西只为交流提高,一起学习,还望大神多加指点,指出纰漏,和提出宝贵的意见,博客会坚持写 ...
- JZOJ 1266. 玉米田
1266. 玉米田(cowfood.pas/c/cpp) (File IO): input:cowfood.in output:cowfood.out Time Limits: 1000 ms Me ...
- python3:判断手机的亮屏状态
在用python对手机做一些自动化操作时,常常会判断手机的亮屏状态,知晓手机的亮屏状态后才好做进一步的动作,如给屏幕解锁等. 用于了解手机的亮屏情况,有一个adb命令可用: adb shell du ...
- 用django实现邮件发送
settings配置 EMAIL_HOST = 'smtp.qq.com' # 如果是163换成stmp.163.com EMAIL_PORT = 465 # qq邮箱的端口 EMAIL_HOST_U ...
- bootmem API总结
bootmem_init()函数执行完成后,linux启动初期的bootmem分配器就初始化完成了,可以调用bootmem提供的API分配内存. 这些API在include/linux/bootmem ...
- P1101 单词方阵
题目描述 给一 n \times nn×n 的字母方阵,内可能蕴含多个"yizhong"单词.单词在方阵中是沿着同一方向连续摆放的.摆放可沿着 88 个方向的任一方向,同一单词摆放 ...
- Fiddler用AutoResponder实现app升级异步更新
先说一下我自己理解的异步更新:用app异步升级举例,app是否升级的检查是在启动app时访问服务器的,把app本地的最新版本号与服务器端的最新版本号做对比,假如不一致,则提示升级.但本次已经打开使用a ...