网络流24题 之十五 汽车加油行驶问题 分层图

题目大意:给出一张网格图,描述了每个点是否是加油站,然后给出以下规则。

1.油量限制,一次加油之后只能行驶k步,向下行驶和向右行驶的时候不增加花费,否则增加B的花费。

2.在没油的时候,若该点没有加油站,就建立一个加油站。花费C。

3.加油花费A。

思路:分层图。f[i][j][k]表示在(i,j)处油箱中还有k的油的时候的最小花费,然后分三种情况更新。

(delta = 往回走的B花费)

1.若当前节点有加油站,就必须加油。到下一个节点是还有k - 1的油量,花费last + A + delta

2.如果当前节点没有加油站,若当前车里还有油,就继续向下更新,花费last + delta

3.如果当前节点没有加油站,若当前车里没有油,就新建一个加油站,花费last + A + C + delta

CODE:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 110
#define INF 0x3f3f3f3f
using namespace std;
const int dx[5] = {0,1,0,-1,0};
const int dy[5] = {0,0,1,0,-1};

struct Complex{
	int x,y,odd;
	Complex(int _,int __,int ___):x(_),y(__),odd(___) {}
	Complex() {}
};

int cnt,k,add_oil,back_cost,new_cost;
int f[MAX][MAX][20];
bool v[MAX][MAX][20],map[MAX][MAX];

void SPFA();

int main()
{
	cin >> cnt >> k >> add_oil >> back_cost >> new_cost;
	for(int i = 1;i <= cnt; ++i)
		for(int j = 1;j <= cnt; ++j)
			scanf("%d",&map[i][j]);
	SPFA();
	int ans = INF;
	for(int i = 0;i <= k; ++i)
		ans = min(ans,f[cnt][cnt][i]);
	cout << ans << endl;
	return 0;
}

void SPFA()
{
	memset(f,0x3f,sizeof(f));
	f[1][1][k] = 0;
	static queue<Complex> q;
	while(!q.empty())	q.pop();
	q.push(Complex(1,1,k));
	while(!q.empty()) {
		Complex now = q.front(); q.pop();
		int last = f[now.x][now.y][now.odd];
		v[now.x][now.y][now.odd] = false;
		for(int i = 1;i <= 4; ++i) {
			int detla = (i > 2) * back_cost;
			int fx = now.x + dx[i];
			int fy = now.y + dy[i];
			if(!fx || !fy || fx > cnt || fy > cnt)	continue;
			if(map[now.x][now.y]) {
				if(f[fx][fy][k - 1] > last + add_oil + detla) {
					f[fx][fy][k - 1] = last + add_oil + detla;
					if(!v[fx][fy][k - 1])
						v[fx][fy][k - 1] = true,q.push(Complex(fx,fy,k - 1));
				}
			}
			else {
				if(!now.odd) {
					if(f[fx][fy][k - 1] > last + add_oil + new_cost + detla) {
						f[fx][fy][k - 1] = last + add_oil + new_cost + detla;
						if(!v[fx][fy][k - 1])
							v[fx][fy][k - 1] = true,q.push(Complex(fx,fy,k - 1));
					}
				}
				else {
					if(f[fx][fy][now.odd - 1] > last + detla) {
						f[fx][fy][now.odd - 1] = last + detla;
						if(!v[fx][fy][now.odd - 1])
							v[fx][fy][now.odd - 1] = true,q.push(Complex(fx,fy,now.odd - 1));
					}
				}
			}
		}
	}
}
时间: 2024-10-13 06:43:38

网络流24题 之十五 汽车加油行驶问题 分层图的相关文章

【线性规划与网络流24题】汽车加油行驶问题 分层图

汽车加油行驶问题 Time Limit: 1 Sec  Memory Limit: 128 MB Description 给定一个 N*N的方形网格,设其左上角为起点◎,坐标为( 1,1),X轴向右为正, Y轴向下为正,每一个方格边长为 1,如图所看到的.一辆汽车从起点◎出发驶向右下角终点▲,其坐标为( N,N).在若干个网格交叉点处,设置了油库,可供汽车在行驶途中加油.汽车在行驶过程中应遵守例如以下规则: (1)汽车仅仅能沿网格边行驶,装满油后能行驶 K条网格边.出发时汽车已装满油,在起点与终

【网络流24题】 No.14 孤岛营救问题 (分层图最短路)

[题意] 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛, 营救被敌军俘虏的大兵瑞恩. 瑞恩被关押在一个迷宫里, 迷宫地形复杂, 但幸好麦克得到了迷宫的地形图. 迷宫的外形是一个长方形, 其南北方向被划分为 N 行,东西方向被划分为 M 列,于是整个迷宫被划分为 N× M 个单元.每一个单元的位置可用一个有序数对(单元的行号,单元的列号)来表示.南北或东西方向相邻的 2 个单元之间可能互通, 也可能有一扇锁着的门,或者是一堵不可逾越的墙.迷宫中有一些单元存放着钥匙, 并

网络流24题 之十四 孤岛营救问题 分层图

题目大意:一张网格图,上面有一些点可能有某种钥匙.节点和节点之间可能有门.有些门须要特定的钥匙就能够通过,有些不管怎样都过不去.求从(1,1)開始到(m,n)的最短时间. 思路:分层图+状态压缩. f[i][j][k],当中i和j描写叙述的是当前所在的位置.k是压缩了的当前有哪些钥匙(因为钥匙的数量<=10,所以全部的状态1<<10的空间内就能够搞定).然后向四个方向更新的时候推断能否经过门. CODE: #include <queue> #include <cstdi

网络流24题小结

网络流24题 前言 网络流的实战应用篇太难做了,因此先完善这一部分 ## 第一题:飞行员配对方案 \(BSOJ2542\)--二分图 最优匹配 题意 两国飞行员\(x\)集合\(y\)集合,\(x\)飞行员可以配对特定的\(y\)集合的飞行员(可无),求一对一配对最大数 Solution 二分图最大匹配裸题,最大流实现 建图:(设\(i\in x\)而\(i'\in y\)) \((S,i,1)~(i',T,1)\) 对\((i,j')\)可匹配\((i,j',1)\) Code 略 ## 第二

【网络流24题】餐巾计划(图解)

LOJ 6008[网络流24题]餐巾计划 题解 一张图片说明建图方法: 解说: 这种建图方法完美区分开了"脏餐巾"和"干净餐巾"两种餐巾. 每天一定会有r[i]个脏餐巾,所以源点向每天的"脏餐巾"(图上used)连边,容量r[i],费用是0.另外,前一天的脏餐巾也可以留到下一天再处理,所以每天的used点向下一天的used点连一条边,容量INF,费用是0. 每天会需要r[i]个干净餐巾,所以每天的"干净餐巾"向汇点连边(图上n

【网络流24题】汽车加油行驶问题(最短路)

[网络流24题]汽车加油行驶问题(最短路) 题面 Cogs 题解 还是SPFA呀... 把剩余的油量直接压进状态里面就好 额外加一个原地加油的决策就行 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map

「网络流24题」 题目列表

「网络流24题」 题目列表 序号 题目标题 模型 题解 1 飞行员配对方案问题 二分图最大匹配 <1> 2 太空飞行计划问题 最大权闭合子图 <2> 3 最小路径覆盖问题 二分图最小路径覆盖 <3> 4 魔术球问题 <4> 5 圆桌问题 <5> 6 最长递增子序列问题 <6> 7 试题库问题 <7> 8 机器人路径规划问题 <8> 9 方格取数问题 二分图最大点权独立集 <9> 10 餐巾计划问题

网络流24题 部分总结

网络流24题 部分总结 慢慢写吧... 以前做过一些了: 然后发现也做了不少了,集中写一下. 警告: 题目按照随机顺序排列. 文章中只有建模的方法. 最小路径覆盖问题 http://cogs.pro:8080/cogs/problem/problem.php?pid=728 题目即题解... // It is made by XZZ #include<cstdio> #include<algorithm> #include<cstring> #define File #

网络流24题刷题记录

题目一:飞行员配对方案问题 一群飞行员和另一群飞行员之间有的可以配对,有的不能配对,求最多可以配多少对? 典型二分图最大匹配问题.可以用匈牙利算法 或者 加上源点汇点之后跑最大流.[感觉第二个打错的概率还低一些]. [还是介绍一下匈牙利算法吧][看白书大法好!] 从左边(s集)一个未盖点出发(还有没有和任何人匹配的点)出发,顺次经过未选边->选边->未选边.....[这样的路叫做交替路] 如果路径当中经过一个未盖点[这样的交替路叫增广路]...那么将所有的选边变成不选,不选的边选上,就可以多一