«问题描述:
给定一个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)的更多相关文章

  1. P4009 汽车加油行驶问题

    P4009 汽车加油行驶问题 最短路 清一色的spfa....送上一个堆优化Dijkstra吧(貌似代码还挺短) 顺便说一句,堆优化Dj跑分层图灰常好写 #include<iostream> ...

  2. 洛谷 P4009 汽车加油行驶问题 解题报告

    P4009 汽车加油行驶问题 题目描述 给定一个\(N×N\)的方形网格,设其左上角为起点◎,坐标(1,1) ,\(X\)轴向右为正,\(Y\)轴向下为正,每个方格边长为1 ,如图所示. 一辆汽车从起 ...

  3. 【题解】【网络流24题】汽车加油行驶问题 [P4009] [Loj6223]

    [题解][网络流24题]汽车加油行驶问题 [P4009] [Loj6223] 传送门:汽车加油行驶问题 \([P4009]\) \([Loj6223]\) [题目描述] 给出一个 \(N \times ...

  4. 【网络流24题】 No.15 汽车加油行驶问题 (分层图最短路i)

    [题意] 问题描述:给定一个 N*N 的方形网格,设其左上角为起点◎, 坐标为( 1, 1), X 轴向右为正, Y轴向下为正, 每个方格边长为 1, 如图所示. 一辆汽车从起点◎出发驶向右下角终点▲ ...

  5. 【刷题】LOJ 6223 「网络流 24 题」汽车加油行驶问题

    题目描述 给定一个 \(\text{N}\times \text{N}\) 的方形网格,设其左上角为起点◎,坐标为 \(\text{(1,1)}\) ,\(\text{X}\) 轴向右为正, \(\t ...

  6. 洛谷P4009 汽车加油行驶问题

    题目描述 给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示. 一辆汽车从起点◎出发 ...

  7. 【洛谷4009】汽车加油行驶问题(SPFA乱搞)

    点此看题面 大致题意:给定一个\(N*N\)的方形网格,其中1表示这个格子有油库,0表示这个格子没油库,且汽车加满油可以行驶\(k\)条网格边.如果遇到油库必须加满油并花费\(A\)元,如果\(X\) ...

  8. 洛谷P4009 汽车加油行驶问题(分层最短路)

    传送门 说好的网络流24题呢……上次是状压dp,这次怎么又最短路了…… 不过倒是用这题好好学了一下分层图最短路 把每一个位置$(x,y)$,油量剩余$k$表示为一个状态,然后转化成一个$n$进制数,这 ...

  9. 洛谷P4009汽车加油行驶问题——网络流24题(最短路)

    题目:https://www.luogu.org/problemnew/show/P4009 网络流24题中不是网络流的最短路题: 把每个点拆成各个油量上的点,根据要求连边即可: 注意:点数最大为10 ...

随机推荐

  1. cocoapods 类库管理利器

    作为iOS开发者,第三方类库的使用是最经常的,但鉴于第三方类库的不断更新以及其可能需要依存其他类,如果要使用最新版那么我们需要重新下载再添加到项目中,无疑带来一些繁琐的麻烦,那么现在这里就有一款能解决 ...

  2. webpack 4.x 解决 webpack-dev-server工具在webpack构建的项目中使用问题

    webpack-dev-server工具能实现自动打包编译和热更新 首先将webpack-dev-server安装到项目中 npm install webpack-dev-server -D 这时在命 ...

  3. [BZOJ] 3301: [USACO2011 Feb] Cow Line

    康拓展开/逆展开 模板 #include<algorithm> #include<iostream> #include<cstdio> #define int lo ...

  4. Iframe父子间元素操作

    1.在父页面 获取iframe子页面的元素 (在同域的情况下 且在http://下测试,且最好在iframe onload加载完毕后 dosomething...) js写法 a.通过contentW ...

  5. Java 技术栈

    JAVA是一个面向对象的编程语言,由SUN公司的程序员所开发.它不仅吸收了C++的各种优点,而且还撇弃了C++中难以理解的概念,如多继承.指针等:因此JAVA语言具有功能强大且简单易用两个特征, JA ...

  6. JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数

    4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms  Memory Limits: 262144 KB  Detailed ...

  7. Python周末21天笔记

    模块一: 基础相互据类型之间的相互转换 1. 字符串str 与 列表 list 与字典 dict 以及 元祖tuple的转换 例一: 把字典的key和value的值取出来,按照顺序存入到list中 d ...

  8. 721. Accounts Merge

    https://leetcode.com/problems/accounts-merge/description/ class UnionFound { public: unordered_map&l ...

  9. 常州大学新生寒假训练会试 I 合成反应

    题目描述 有机合成是指从较简单的化合物或单质经化学反应合成有机物的过程. 有时也包括从复杂原料降解为较简单化合物的过程. 由于有机化合物的各种特点,尤其是碳与碳之间以共价键相连,有机合成比较困难,常常 ...

  10. HDU2586 How far away ?

    一.描述 很久没写代码了,在之前一直在参与准备ASC比赛和美赛,现在又重新捡起来.目标是两个月后的邀请赛. 这题是树链拋分解决LCA问题的一个模板题. 首先介绍下树链拋分的基本思想. 对于任意一颗树, ...