题目链接:https://www.luogu.org/problemnew/show/P4012

洛谷 P4012 深海机器人问题

输入输出样例

输入样例#1:

1 1
2 2
1 2
3 4
5 6
7 2
8 10
9 3
2 0 0
2 2 2
输出样例#1:

42

说明

题解:建图方法如下:

  对于矩阵中的每个点,向东、向北分别与其相邻点都要连两条边(重边):

    1)容量为1,费用为该边价值的边;

    2)容量为INF,费用为0的边(因为多个深海机器人可以在同一时间占据同一位置)。

  对于每个起点:从S(源点)到这个点连:容量为该点机器人数,费用为0的边。

  对于每个终点:从这个点到T(汇点)连:容量为该点机器人数,费用为0的边。

代码:

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
const int M = N*+;
const int INF = 0x3f3f3f3f;
struct Edge { int to,next,cap,flow,cost; }edge[M];
int head[N],tol;
int pre[N],dis[N];
bool vis[N];
int V;
void init(int n) {
V = n;
tol = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int cap,int cost) {
edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = ; edge[tol].next = head[u]; head[u] = tol++;
edge[tol].to = u; edge[tol].cap = ; edge[tol].cost = -cost; edge[tol].flow = ; edge[tol].next = head[v]; head[v] = tol++;
}
bool spfa(int s,int t) {
queue<int>q;
for(int i = ;i < V;i++) {
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while(!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u]; i != -;i = edge[i].next) {
int v = edge[i].to;
if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) {
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if(!vis[v]) {
vis[v] = true;
q.push(v);
}
}
}
}
if(pre[t] == -) return false;
else return true;
}
int minCostMaxflow(int s,int t,int &cost) {
int flow = ;
cost = ;
while(spfa(s,t)) {
int Min = INF;
for(int i = pre[t];i != -;i = pre[edge[i^].to]) {
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for(int i = pre[t];i != -;i = pre[edge[i^].to]) {
edge[i].flow += Min;
edge[i^].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
}
int main() {
int a, b, p, q, k, x, y, i, j, ans = ;
scanf("%d%d", &a, &b);//出发和目的地数目
scanf("%d%d", &p, &q);
init((p+)*(q+)+); int s = (p+)*(q+)+, t = (p+)*(q+)+; for(i = ; i <= p; ++i) {//p+1行,向东移动
for(j = ; j < q; ++j) {
scanf("%d", &x);//边上的标本价值
addedge(i*(q+)+j, i*(q+)+j+, , -x);
addedge(i*(q+)+j, i*(q+)+j+, INF, );
}
}
for(j = ; j <= q; ++j) {//q+1列,向北移动
for(i = ; i < p; ++i) {
scanf("%d", &x);
addedge(i*(q+)+j, i*(q+)+j+q+, , -x);
addedge(i*(q+)+j, i*(q+)+j+q+, INF, );
}
}
for(i = ; i <= a; ++i) {//起点
scanf("%d%d%d", &k, &x, &y);
addedge(s, x*(q+)+y, k, );
}
for(i = ; i <= b; ++i) {//终点
scanf("%d%d%d", &k, &x, &y);
addedge(x*(q+)+y, t, k, );
}
minCostMaxflow(s, t, ans);
printf("%d\n", -ans);
return ;
}

洛谷 P4012 深海机器人问题【费用流】的更多相关文章

  1. 洛谷P4012 深海机器人问题(费用流)

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

  2. 洛谷P4012 深海机器人问题(费用流)

    传送门 图给的好坑……还得倒过来…… 用大佬的图做个示范 我们考虑左图吧 把每一个点向下连边,容量$1$,费用为给出的价值(表示一个机器人可以过去取得标本) 再连一条边,容量$inf$,费用$0$(表 ...

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

    和火星那个有点像,但是这个价值直接在路径上,不用拆点,对于每条价值为w的边(i,j),连接(i,j,1,w)(i,j,inf,0),表示价值只能取一次,然后连接源点和所有出发点(s,i,k,0),所有 ...

  4. LuoguP4012 深海机器人问题(费用流)

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

  5. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  6. 洛谷P4003 无限之环(费用流)

    传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...

  7. 洛谷P3356 火星探险问题(费用流)

    题目描述 火星探险队的登陆舱将在火星表面着陆,登陆舱内有多部障碍物探测车.登陆舱着陆后,探测车将离开登陆舱向先期到达的传送器方向移动.探测车在移动中还必须采集岩石标本.每一块岩石标本由最先遇到它的探测 ...

  8. 洛谷P2517 HAOI2010 订货 (费用流)

    标准的费用流问题,关键在于巧妙地建模 一共有n个月份,源点设为0,汇点设为n+1 1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用 2.每个月向下一个月连边,容量为仓库容量,费用为存货费用 ...

  9. 洛谷P4016 负载平衡问题 费用流

    这道题还是很好的. 考察了选手对网络流的理解. 首先,任意两个相邻点之间的运货量时没有限制的. 我们可以将相邻点之间的流量建为无限大,单位费用设为 1,代表运输一个货物需耗费一个代价. 由于题目要求最 ...

随机推荐

  1. jquery序列化from表单使用ajax提交返回json数据(使用struts2注解result type = json)

    1.action类引入struts2的"json-default"拦截器栈 @ParentPackage("json-default") //示例 @Paren ...

  2. CSS3 颜色属性

    关键字颜色 red 十六进制颜色 #FF0000 RGB颜色   rgb(255,0,0) 新增的颜色表示方法 RGBa: RGB代表光的三原色,Red.Green和Blue CSS3中可以增加一个值 ...

  3. JavaScript 学习(一)

        此篇为学习笔记 JS 简介 JavaScript 是一种轻量级的脚本编程语言JavaScript 是可插入 HTML 页面的编程代码.JavaScript 插入 HTML 页面后,可由所有的现 ...

  4. spark算子集锦

    Spark 是大数据领域的一大利器,花时间总结了一下 Spark 常用算子,正所谓温故而知新. Spark 算子按照功能分,可以分成两大类:transform 和 action.Transform 不 ...

  5. Mysql explain分析sql语句执行效率

    mysql优化–explain分析sql语句执行效率 Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 ...

  6. Spring中的IOC示例

    Spring中的IOC示例 工程的大概内容是: 一个人在中国时用中国话问候大家,在国外时用英语问候大家. 其中, IHelloMessage是接口,用来定义输出问候信息 public interfac ...

  7. 对io进行分流

    package org.richin.io.Stream.util;     import java.io.BufferedInputStream;     import java.io.Buffer ...

  8. UNIX 高手的另外 10 个习惯

    让我们面对现实吧:坏习惯很难改变.但是您已经熟悉的习惯可能更难克服.有时,重新审视某些事情可能让您遇到“啊哈,我没想到它能做到这一点!”的时刻.在 Michael Stutz 的优秀文章“UNIX 高 ...

  9. 记一次Android studio升级之后的坑

    像往常一样打开Android studio,但这次它提示我升级!说是什么为了更好的体验,在好奇心的驱使下,我毅然地点击了“update”按钮.升级之后,编译项目,报出了N多个error,我的心都慌完! ...

  10. BlockingQueue介绍及使用

    1.BlockingQueue队列和平常队列一样都可以用来作为存储数据的容器,但有时候在线程当中 涉及到数据存储的时候就会出现问题,而BlockingQueue是空的话,如果一个线程要从Blockin ...