关键词:最小费用最大流

题目大意:海底是个网格,每个网格边有一定价值的海底化石。每个路线可经过无限个机器人,但上面的化石只能采一次。机器人可沿网格边向东或向北移动。给定机器人起点和终点位置及所能容纳的机器人数,求能获得的最大价值。

网络流:把一个机器人运动的轨迹看作一个流量为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 深海机器人问题 网络流的更多相关文章

  1. 【网络流24题】No. 20 深海机器人问题 (费用流)

    [题意] 深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人. 潜艇到达深海海底后, 深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本. 沿 ...

  2. 【刷题】LOJ 6224 「网络流 24 题」深海机器人问题

    题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...

  3. 【PowerOJ1755&网络流24题】深海机器人问题(费用流)

    题意: 思路: [问题分析] 最大费用最大流问题. [建模方法] 把网格中每个位置抽象成网络中一个节点,建立附加源S汇T. 1.对于每个顶点i,j为i东边或南边相邻的一个节点,连接节点i与节点j一条容 ...

  4. [洛谷P4012] [网络流24题] 深海机器人问题

    Description 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生 ...

  5. (luogu P4012)深海机器人问题 [TPLY]

    网页链接 https://www.luogu.org/problemnew/show/4012 做题背景 在不久的将来,人工智能发展使得人类大量失业,也使得现在的我们做[深海机器人问题]做得想死... ...

  6. 洛谷 P4012 深海机器人问题【费用流】

    题目链接:https://www.luogu.org/problemnew/show/P4012 洛谷 P4012 深海机器人问题 输入输出样例 输入样例#1: 1 1 2 2 1 2 3 4 5 6 ...

  7. luogu P4012 深海机器人问题

    luogu P4012 深海机器人问题 // luogu-judger-enable-o2 #include<queue> #include<cstdio> #include& ...

  8. P4012 深海机器人问题

    \(\color{#0066ff}{题目描述}\) 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人 ...

  9. 深海机器人(cogs 742)

    «问题描述:深海资源考察探险队的潜艇将到达深海的海底进行科学考察.潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动.深海机器人在移动中还必须沿途采集海底生物标本.沿途生物 ...

随机推荐

  1. ACM_开心消消乐

    开心消消乐 Time Limit: 2000/1000ms (Java/Others) Problem Description: 大白最近喜欢上了开心消消乐,于是英语基础好的他准备让课文中英语句子也来 ...

  2. 5.27 sorm图

  3. 看懂SqlServer执行计划

    在园子看到一篇SQLServer关于查询计划的好文,激动啊,特转载.原文出自:http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.htm ...

  4. Oracle数据库的导入和导出

    Oracle数据库的导入和导出,是一项重要的的技术活,不但解决了数据库的导入导出,更方便快捷的获得数据. 使用imp和exp导入导出数据 使用exp导出数据 存放目录为\ORACLE_HOME\BIN ...

  5. 安卓代码迁移:Make.exe: *** [***.o]Error 1

    描述:NDK开发中显示,windows环境下NDK开发 解决办法:查找系统环境变量,找到关于Cygwin的环境变量或其他无效的环境变量删除处理.

  6. 【JSP】中文乱码问题

     原作者http://www.cnblogs.com/xing901022/p/4354529.html 阅读目录 之前总是碰到JSP页面乱码的问题,每次都是现在网上搜,然后胡乱改,改完也不明白原因. ...

  7. HDU_1969_二分

    Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  8. Javascript语法,变量类型,条件,循环语句,函数,面向对象

    1.JavaScript代码革两种存在形式: <!-- 方式一 --> <script type='txt/javascript' src='/js/comment.js'>& ...

  9. php多进程防止出现僵尸进程

    对于用PHP进行多进程并发编程,不可避免要遇到僵尸进程的问题. 僵尸进程是指的父进程已经退出,而该进程dead之后没有进程接受,就成为僵尸进程(zombie)进程.任何进程在退出前(使用exit退出) ...

  10. [IOI2007]矿工配餐

    状态是f[i][a][b][c][d]表示第i个餐车,1号矿洞最近两顿是a,b,2号矿洞最近两顿是c,d. 给的空间是16MB,滚动数组滚动了第一维就行了 (给的变量是char是因为这个不超过256, ...