题目描述

给定一个 N \times NN×N 的方形网格,设其左上角为起点◎,坐标(1,1)(1,1),XX 轴向右为正, YY 轴向下为正,每个方格边长为 11 ,如图所示。

一辆汽车从起点◎出发驶向右下角终点▲,其坐标为 (N,N)(N,N)。

在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油。汽车在行驶过程中应遵守如下规则:

  1. 汽车只能沿网格边行驶,装满油后能行驶 KK 条网格边。出发时汽车已装满油,在起点与终点处不设油库。

  2. 汽车经过一条网格边时,若其 XX 坐标或 YY 坐标减小,则应付费用 BB ,否则免付费用。

  3. 汽车在行驶过程中遇油库则应加满油并付加油费用 AA。

  4. 在需要时可在网格点处增设油库,并付增设油库费用 CC(不含加油费用AA )。

  5. N,K,A,B,CN,K,A,B,C 均为正整数, 且满足约束: 2\leq N\leq 100,2 \leq K \leq 102≤N≤100,2≤K≤10。

设计一个算法,求出汽车从起点出发到达终点所付的最小费用。

输入输出格式

输入格式:

文件的第一行是 N,K,A,B,CN,K,A,B,C 的值。

第二行起是一个N\times NN×N 的 0-10−1 方阵,每行 NN 个值,至 N+1N+1 行结束。

方阵的第 ii 行第 jj 列处的值为 11 表示在网格交叉点 (i,j)(i,j) 处设置了一个油库,为 00 时表示未设油库。各行相邻两个数以空格分隔。

输出格式:

程序运行结束时,输出最小费用。

输入输出样例

输入样例#1:

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
输出样例#1:

12

分层最短路板子题,讲在i行,j列,还剩k油为一个状态,其中建出这个点为k*n*n+i*n+j然后分出加油和跑路,跑一边SPFA即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 200100
#define INF 10000009
#define MOD 10000007
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(int i=k;i<=n;i++)
#define DREP(i,k,n) for(int i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
inline int read(){
int x=,f=;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-;
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
return x*f;
}
inline void out(int x){
if(x<) putchar('-'),x=-x;
if(x>) out(x/);
putchar(x%+'');
}
int n,k,a,b,c;
deque <int> Q;
int ans=;
int dis[MAXN],vis[MAXN];
int total=,head[MAXN<<],nxt[MAXN<<],to[MAXN<<],val[MAXN<<];
inline int calc(int l,int i,int j){
return n*n*l+n*i+j;
}
inline void adl(int a,int b,int c){
total++;
to[total]=b;
val[total]=c;
nxt[total]=head[a];
head[a]=total;
return ;
}
inline void SPFA(){
memset(dis,,sizeof(dis));
Q.push_back(calc(k,,));
dis[calc(k,,)]=;
vis[calc(k,,)]=;
while(!Q.empty()){
int u=Q.front();
Q.pop_front();
vis[u]=;
for(int e=head[u];e;e=nxt[e])
if(dis[to[e]]>dis[u]+val[e]){
dis[to[e]]=dis[u]+val[e];
if(vis[to[e]]) continue;
vis[to[e]]=;
if(!Q.empty())
if(dis[to[e]]<dis[Q.front()]) Q.push_front(to[e]);
else Q.push_back(to[e]);
else Q.push_back(to[e]);
}
}
return ;
}
int main(){
in(n);in(k);in(a);in(b);in(c);
REP(i,,n-)
REP(j,,n-){
int x;
in(x);
if(x || (!i && !j)){
REP(l,,k-) adl(calc(l,i,j),calc(k,i,j),a);
if(i!=n-) adl(calc(k,i,j),calc(k-,i+,j),);
if(j!=n-) adl(calc(k,i,j),calc(k-,i,j+),);
if(i) adl(calc(k,i,j),calc(k-,i-,j),b);
if(j) adl(calc(k,i,j),calc(k-,i,j-),b);
}
else{
REP(l,,k-) adl(calc(l,i,j),calc(k,i,j),a+c);
REP(l,,k){
if(i!=n-) adl(calc(l,i,j),calc(l-,i+,j),);
if(j!=n-) adl(calc(l,i,j),calc(l-,i,j+),);
if(i) adl(calc(l,i,j),calc(l-,i-,j),b);
if(j) adl(calc(l,i,j),calc(l-,i,j-),b);
}
}
}
SPFA();
ans=INF;
REP(i,,k) ans=min(ans,dis[calc(i,n-,n-)]);
out(ans);
return ;
}

洛谷P4009 汽车加油行驶问题的更多相关文章

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

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

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

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

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

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

  4. 洛谷 P4009 汽车加油行驶问题 【最小费用最大流】

    分层图,建k层,设(i,j,0)为点(i,j)的满油状态,全图的流量都是1,因为重复走到一个点没有意义.如果当前点是加油站,那么它向它上左的点连费用为a的边,向下右连费用为a+b的边: 否则,这个点的 ...

  5. P4009 汽车加油行驶问题

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

  6. Luogu P4009 汽车加油行驶问题

    题目链接 \(Click\) \(Here\) 分层图..好长时间没写差点要忘了\(hhhhh\),其实思路还是很明了的. 注意需要强制消费. #include <bits/stdc++.h&g ...

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

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

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

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

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

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

随机推荐

  1. JS设计模式——1.富有表现力的JS

    创建支持链式调用的类(构造函数+原型) Function.prototype.method = function(name, fn){ this.prototype[name] = fn; retur ...

  2. 设计模式之Adapter

    设计模式总共有23种模式这仅仅是为了一个目的:解耦+解耦+解耦...(高内聚低耦合满足开闭原则) 介绍: 将两个不兼容的类纠合在一起使用,属于结构型模式,也有人称它为wrapper(包装类). 包装类 ...

  3. netif_receive_skb->__netif_receive_skb_core

    在设备驱动收包之后,会通过netif_receive_skb将收取的包,按照注册的协议回调,传递到上层进行处理: /* 将skb传递到上层 */ static int __netif_receive_ ...

  4. 64_t6

    texlive-recipebook-svn37026.0-33.fc26.2.noarch.rpm 24-May-2017 15:44 37946 texlive-recipecard-doc-sv ...

  5. git 还原到指定版本号

      git clone git branch -r --contains 88b92060224e96ef209565fa75c816eb9b0fae8e git checkout origin/re ...

  6. 教你如何更改android应用的包名

    Android 源码自带了很多应用程序,想改个包名方便修改?很简单,两步搞定,以packages/apps/Settings为例: 1.打开AndroidManifest.xml,把 <mani ...

  7. CSU 1412 Line and Circles

    原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1412 题目要求判断是否有一条直线可以穿过所有的圆. 做法:把所有圆心做一次凸包,然后判断 ...

  8. 计算 Python (list or array) 相同索引元素相等的个数

    上代码: a = [2, 3, 3, 1, 1, 3, 3, 3, 2, 1, 3, 1, 3, 2, 2, 2, 3, 1, 2, 3, 2, 3, 1, 1, 2, 1, 1, 1, 2, 2, ...

  9. MYSQL-----流程控制 if() 函数的用法

    语法:IF(condition,result,result) 如果函数的第一个参数中给定的condition符合条件(如,condition不等于0或者不为NULL),那么函数的执行结果为第二个参数中 ...

  10. Ubuntu16.4 修改静态ip地址

    root@temple-102:~# ifconfig eno1 Link encap:Ethernet HWaddr 0c:c4:7a:e6:49:74 UP BROADCAST MULTICAST ...