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)
«问题描述:深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动.深海机器人在移动中还必须沿途采集海底生物标本.沿途生物 ...
随机推荐
- DOM 介绍
什么时DOM DOM:文档对象模型.DOM为文档提供了结构化表示,并定义了如何通过脚本来范文文档结构.目的起始就是为了能让js操作html元素而指定的一个规范. DOM就是由节点组成的. 解析过程 H ...
- 基于artDialog的扩展
/* * * 引用此文件必须引用以下两个资源文件,并且还要引用jQuery * <link href="ui-dialog.css" rel="stylesheet ...
- windows下查看端口进程占用情况
引用:http://jingyan.baidu.com/article/3c48dd34491d47e10be358b8.html 我们在启动应用的时候经常发现我们需要使用的端口被别的程序占用,但是我 ...
- 【Linux】七种运行级别
运行级别:即系统的运行模式. 级别类型: 0:关机状态. 1:单用户模式. 2:字符界面的多用户模式(不支持网络). 3:字符界面的多用户模式(运行最完整的模式). 4:未分配使用,系统保留. 5:图 ...
- 连接Oracle数据库帮助类
连接Oracle数据库帮助类,就是把连接Oracle数据库的方法封装起来,只需要在其它页面调用就可,不需要重复写. import java.sql.Connection; import java.sq ...
- dubbo之多注册中心
Dubbo 支持同一服务向多注册中心同时注册,或者不同服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务.另外,注册中心是支持自定义扩展的. 多注册中心注册 比如:中文站 ...
- logger日志
Level 描述 ALL 各级包括自定义级别 DEBUG 指定细粒度信息事件是最有用的应用程序调试 ERROR 错误事件可能仍然允许应用程序继续运行 FATAL 指定非常严重的错误事件,这可能导致应用 ...
- 数据库操作(一)DML
1.数据库 数据库可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增.查询.更新.删除等操作. 所谓“数据库”是以一定方式储存在一起.能与多个用户共享.具有尽可能小的冗余度.与 ...
- 【剑指Offer】13、调整数组顺序使奇数位于偶数前面
题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 解题思 ...
- Cache占用过多内存导致Linux系统内存不足问题排查
问题描述 Linux服务器内存使用量超过阈值,触发报警. 问题排查 首先,通过free命令观察系统的内存使用情况,显示如下: total used free shared buffers cached ...