luogu4012 深海机器人问题 网络流
关键词:最小费用最大流
题目大意:海底是个网格,每个网格边有一定价值的海底化石。每个路线可经过无限个机器人,但上面的化石只能采一次。机器人可沿网格边向东或向北移动。给定机器人起点和终点位置及所能容纳的机器人数,求能获得的最大价值。
网络流:把一个机器人运动的轨迹看作一个流量为1的流。
化石只能采一次,我们想到建立一条容量为1的边,价值为-化石价值。以后该路线可经过无限个机器人,我们想到建立一条容量为∞的边,价值为0。S连起点,终点连T,容量为其所能容纳的机器人数。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cassert>
using namespace std; #define LOOP(i, n) for(int i=1; i<=n; i++)
#define ID(col, row) row * (lastCol + 1) + col + 1
const int MAX_NODE = * , MAX_EDGE = MAX_NODE*MAX_NODE * , INF = 0x3f3f3f3f, MAX_ROW = , MAX_COL = ; struct MCMF
{
struct Node;
struct Edge; struct Node
{
Edge *Head, *Prev;
int Dist, Id;
bool Inq;
}; struct Edge
{
int Cap, Cost, OrgCap;
Node *From, *To;
Edge *Next, *Rev;
Edge(int cap, int cost, Node *from, Node *to, Edge *next) :Cap(cap), OrgCap(cap), Cost(cost), From(from), To(to), Next(next) {}
}; Node _nodes[MAX_NODE];
Edge *_edges[MAX_EDGE];
int _vCount = , _eCount = ;
Node *Start, *Sink;
int TotFlow, TotCost; void Init(int n, int sId, int tId)
{
_vCount = n;
_eCount = ;
Start = &_nodes[sId], Sink = &_nodes[tId];
TotFlow = TotCost = ;
} Edge* AddEdge(Node *from, Node *to, int cap, int cost)
{
Edge *e = _edges[++_eCount] = new Edge(cap, cost, from, to, from->Head);
e->From->Head = e;
return e;
} void Build(int uId, int vId, int cap, int cost)
{
//printf("%d->%d\n", uId, vId);
Node *u = uId + _nodes, *v = vId + _nodes;
u->Id = uId;
v->Id = vId;
Edge *edge1 = AddEdge(u, v, cap, cost), *edge2 = AddEdge(v, u, , -cost);
edge1->Rev = edge2;
edge2->Rev = edge1;
} bool SPFA()
{
queue<Node*> q;
LOOP(i, _vCount)
{
_nodes[i].Prev = NULL;
_nodes[i].Dist = INF;
_nodes[i].Inq = false;
}
Start->Dist = ;
q.push(Start);
while (!q.empty())
{
Node *u = q.front();
q.pop();
u->Inq = false;
for (Edge *e = u->Head; e; e = e->Next)
{
if (e->Cap && u->Dist + e->Cost < e->To->Dist)
{
e->To->Dist = u->Dist + e->Cost;
e->To->Prev = e;
if (!e->To->Inq)
{
e->To->Inq = true;
q.push(e->To);
}
}
}
}
return Sink->Prev;
} void Proceed()
{
while (SPFA())
{
assert(Sink->Dist != INF);
int minFlow = INF;
for (Edge *e = Sink->Prev; e; e = e->From->Prev)
minFlow = min(minFlow, e->Cap);
TotFlow += minFlow;
for (Edge *e = Sink->Prev; e; e = e->From->Prev)
{
e->Cap -= minFlow;
e->Rev->Cap += minFlow;
TotCost += minFlow * e->Cost;
}
}
}
}g; int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totStart, totTarget, lastCol, lastRow,
row, col, horiVal, vertVal, robotCnt;
scanf("%d%d%d%d", &totStart, &totTarget, &lastRow, &lastCol);
int sId = ID(lastCol, lastRow) + , tId = ID(lastCol, lastRow) + ;
g.Init(tId, sId, tId);
for (int row = ; row <= lastRow; row++)
for (int col = ; col <= lastCol; col++)
{
scanf("%d", &horiVal);
g.Build(ID((col - ), row), ID(col, row), INF, );
g.Build(ID((col - ), row), ID(col, row), , -horiVal);
}
for (int col = ; col <= lastCol; col++)
for (int row = ; row <= lastRow; row++)
{
scanf("%d", &vertVal);
g.Build(ID(col, (row - )), ID(col, row), INF, );
g.Build(ID(col, (row - )), ID(col, row), , -vertVal);
}
LOOP(i, totStart)
{
scanf("%d%d%d", &robotCnt, &row, &col);
g.Build(sId, ID(col, row), robotCnt, );
}
LOOP(i, totTarget)
{
scanf("%d%d%d", &robotCnt, &row, &col);
g.Build(ID(col, row), tId, robotCnt, );
}
g.Proceed();
printf("%d\n", -g.TotCost);
return ;
}
注意:宏替换写函数时,对其所操作的参数尽量打括号,否则会出现运算顺序问题。
luogu4012 深海机器人问题 网络流的更多相关文章
- 【网络流24题】No. 20 深海机器人问题 (费用流)
[题意] 深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人. 潜艇到达深海海底后, 深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本. 沿 ...
- 【刷题】LOJ 6224 「网络流 24 题」深海机器人问题
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
- 【PowerOJ1755&网络流24题】深海机器人问题(费用流)
题意: 思路: [问题分析] 最大费用最大流问题. [建模方法] 把网格中每个位置抽象成网络中一个节点,建立附加源S汇T. 1.对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点i与节点j一条容 ...
- [洛谷P4012] [网络流24题] 深海机器人问题
Description 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生 ...
- (luogu P4012)深海机器人问题 [TPLY]
网页链接 https://www.luogu.org/problemnew/show/4012 做题背景 在不久的将来,人工智能发展使得人类大量失业,也使得现在的我们做[深海机器人问题]做得想死... ...
- 洛谷 P4012 深海机器人问题【费用流】
题目链接:https://www.luogu.org/problemnew/show/P4012 洛谷 P4012 深海机器人问题 输入输出样例 输入样例#1: 1 1 2 2 1 2 3 4 5 6 ...
- luogu P4012 深海机器人问题
luogu P4012 深海机器人问题 // luogu-judger-enable-o2 #include<queue> #include<cstdio> #include& ...
- P4012 深海机器人问题
\(\color{#0066ff}{题目描述}\) 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人 ...
- 深海机器人(cogs 742)
«问题描述:深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动.深海机器人在移动中还必须沿途采集海底生物标本.沿途生物 ...
随机推荐
- 跳出双重for循环的案例__________跳出了,则不再执行标签ok下的for循环代码
ok: for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { System.out.print("*" ...
- 自学Python九 爬虫实战二(美图福利)
作为一个新世纪有思想有文化有道德时刻准备着的屌丝男青年,在现在这样一个社会中,心疼我大慢播抵制大百度的前提下,没事儿上上网逛逛YY看看斗鱼翻翻美女图片那是必不可少的,可是美图虽多翻页费劲!今天我们就搞 ...
- 【Linux】七种运行级别
运行级别:即系统的运行模式. 级别类型: 0:关机状态. 1:单用户模式. 2:字符界面的多用户模式(不支持网络). 3:字符界面的多用户模式(运行最完整的模式). 4:未分配使用,系统保留. 5:图 ...
- Mongo连接远程数据库
mongo IP+Port CrabyterV5 首先这么操作是基于配置了环境变量的,可以参照http://www.cnblogs.com/daiyonghui/p/5209076.html mong ...
- 关于php初学者的理解!请大家浏览并指出不足!谢谢!
昨天开始学习php,由于之前是学习.NET的,刚接触php,就关于语法就是各种不适应,什么js,jq在脑子里一团浆糊..过了一天感觉好了点,现在有点想法,大家欢迎交流批评! 今天用php做了个登录,判 ...
- JAVA语言编程格式高级规范
作为一位开发人员,都要有严格的代码规范.为此我总结了一些代码规范案例. 目 录 1. 前言 2. 试用范围 3. JAVA命名规范-- 3.1 公共约定 3.2 Java文件.包 3.3 类.接口 ...
- C++多行文本读取
使用的多行读取的代码如下: //读取文本浮点数到多个模式 序列 bool CPicToolsDlg::readTxt2SeqMulti( std::string TxtName, std::vecto ...
- texi格式文件的读取
使用texi2html可以将texi格式的文件转换成html格式的文件. sudo apt-get install texi2html 在对应目录下 texi2html filename.texi 或 ...
- 【JSP】简单登陆界面
学生登陆查询系统 1 程序的主要功能及特点 实现一个登录界面的基本功能,具体要求: 登录界面login.jsp含有表单,用户能够输入用户名和密码,并提交表单给verify.jsp. Verify.js ...
- java 发送http请求
参考别人的 package test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputS ...