Problem Statement

Snuke is playing with red and blue balls, placing them on a two-dimensional plane.

First, he performed $N$ operations to place red balls. In the $i$-th of these operations, he placed $RC_i$ red balls at coordinates $(RX_i,RY_i)$.
Then, he performed another $N$ operations to place blue balls. In the $i$-th of these operations, he placed $BC_i$ blue balls at coordinates $(BX_i,BY_i)$.
The total number of red balls placed and the total number of blue balls placed are equal, that is, $\sum_{i=1}^{N} RC_i = \sum_{i=1}^{N} BC_i$. Let this value be $S$.

Snuke will now form $S$ pairs of red and blue balls so that every ball belongs to exactly one pair.
Let us define the score of a pair of a red ball at coordinates $(rx, ry)$ and a blue ball at coordinates $(bx, by)$ as $|rx-bx| + |ry-by|$.

Snuke wants to maximize the sum of the scores of the pairs.
Help him by finding the maximum possible sum of the scores of the pairs.

Constraints

  • $1 \leq N \leq 1000$
  • $0 \leq RX_i,RY_i,BX_i,BY_i \leq 10^9$
  • $1 \leq RC_i,BC_i \leq 10$
  • $\sum_{i=1}^{N} RC_i = \sum_{i=1}^{N} BC_i$
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

$N$
$RX_1$ $RY_1$ $RC_1$
$RX_2$ $RY_2$ $RC_2$
$\vdots$
$RX_N$ $RY_N$ $RC_N$
$BX_1$ $BY_1$ $BC_1$
$BX_2$ $BY_2$ $BC_2$
$\vdots$
$BX_N$ $BY_N$ $BC_N$

Output

Print the maximum possible sum of the scores of the pairs.


Sample Input 1

2
0 0 1
3 2 1
2 2 1
5 0 1

Sample Output 1

8

If we pair the red ball at coordinates $(0,0)$ and the blue ball at coordinates $(2,2)$, the score of this pair is $|0-2| + |0-2|=4$.
Then, if we pair the red ball at coordinates $(3,2)$ and the blue ball at coordinates $(5,0)$, the score of this pair is $|3-5| + |2-0|=4$.
Making these two pairs results in the total score of $8$, which is the maximum result.


Sample Input 2

3
0 0 1
2 2 1
0 0 2
1 1 1
1 1 1
3 3 2

Sample Output 2

16

Snuke may have performed multiple operations at the same coordinates.


Sample Input 3

10
582463373 690528069 8
621230322 318051944 4
356524296 974059503 6
372751381 111542460 9
392867214 581476334 6
606955458 513028121 5
882201596 791660614 9
250465517 91918758 3
618624774 406956634 6
426294747 736401096 5
974896051 888765942 5
726682138 336960821 3
715144179 82444709 6
599055841 501257806 6
390484433 962747856 4
912334580 219343832 8
570458984 648862300 6
638017635 572157978 10
435958984 585073520 7
445612658 234265014 6

Sample Output 3

45152033546

Manhattan Max Matching

曼哈顿距离其实挺难处理的,考虑将绝对值拆掉,转化为切比雪夫距离。

\[D=|x_1-x_2|+|y_1-y_2|=\max(|(x_1-y_1)-(x_2-y_2)|,|(x_1+y_1)-(x_2+y_2)|))
\]

这样看起来要跑最大费用最大流,但其实我们更习惯最小费用最大流,加上题目求的也是最小值,所以考虑取负。

\[D=-min((x_1-y_1)-(x_2-y_2),(x_1+y_1)-(x_2+y_2),(x_2+y_2)-(x_1+y_1),(x_2-y_2)-(x_1-y_1))
\]

那么此时我们要求一种匹配,让后面四个式子的 min 之和最小。既然是匹配了,考虑网络流。

先是套路,从源点向每个左节点连边,流量 \(RC_i\),每个右节点向汇点连边,流量\(BC_i\)。

然后考虑如何求出后面四个东西最小值。建立四个虚拟节点 \(s_1,s_2,s_3,s_4\),然后每个左节点 \(i\) 向 \(s_1\) 连一条费用 \(RX_i-RY_i\) 的边,向 \(s_2\) 连一条费用 \(RY_i-RX_i\) 的边,其它同理。然后从 \(s_1\) 向右节点连一条费用为 \(BY_i-BX_i\) 的边,向 \(s_2\) 连一条费用为 \(BX_i-BY_i\) 的边,其它也同理。这一段所说的所有边流量正无穷。

那么此时会发现从点 \(i\) 到 \(j\) 的费用最短路刚好是 \(|RX_i-BX_i|+|RY_i-BY_i|\)。但它有那么多边,怎么让他只走最短路呢?发现跑最小费用最大流时,他自然会走最短路。所以不用考虑这件事。

但是连得费用有负数,这是一件很不好的事,这说明可能出现负环。所以考虑给他们共同加上一个一样的数。但这是否会影响最终答案呢?其实是不会的,因为发现计算中如果给他们加上 \(INF\),那么 \(INF\) 一共会被计算 \(2*S\) 次。所以最后减去是可以的。

记得取负啊。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=4005,T=4000,S1=3999,S2=3998,S3=3997,S4=3996;
const LL INFLL=1e18,INF=2e9+5;
int n,hd[N],e_num(1),vhd[N],q[N*N],l,r,v[N],s;
LL d[N],ans;
struct edge{
int v,nxt,f;
LL w;
}e[N<<3];
int bfs()
{
memcpy(hd,vhd,sizeof(hd));
memset(v,0,sizeof(v));
memset(d,0x7f,sizeof(d));
d[q[l=r=1]=0]=1,v[0]=1;
// printf("%d\n",hd[0]);
while(l<=r)
{
// printf("%d\n",q[l]);
for(int i=hd[q[l]];i;i=e[i].nxt)
{
if(d[e[i].v]>d[q[l]]+e[i].w&&e[i].f)
{
d[e[i].v]=d[q[l]]+e[i].w;
if(!v[e[i].v])
v[q[++r]=e[i].v]=1;
}
}
v[q[l++]]=0;
}
// printf("%lld\n",d[T]);
return d[T]<=INFLL;
}
int dfs(int x,int s)
{
// printf("%d %d\n",x,s);
if(x==T)
return s;
v[x]=1;
LL g;
for(int&i=hd[x];i;i=e[i].nxt)
{
if(e[i].f&&!v[e[i].v]&&d[e[i].v]==d[x]+e[i].w&&(g=dfs(e[i].v,min(s,e[i].f))))
{
e[i].f-=g;
e[i^1].f+=g;
ans+=e[i].w*g;
return g;
}
}
return 0;
}
void add_edge(int u,int v,int f,LL w)
{
e[++e_num]=(edge){v,hd[u],f,w};
hd[u]=e_num;
e[++e_num]=(edge){u,hd[v],0,-w};
hd[v]=e_num;
}
int main()
{
scanf("%d",&n);
for(int i=1,x,y,c;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&c),add_edge(0,i,c,0),s+=c;
add_edge(i,S1,INF,INF+x+y);
add_edge(i,S2,INF,INF+x-y);
add_edge(i,S3,INF,INF-x-y);
add_edge(i,S4,INF,INF+y-x);
}
for(int i=1,x,y,c;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&c),add_edge(i+n,T,c,0);
add_edge(S1,i+n,INF,INF-x-y);
add_edge(S2,i+n,INF,INF+y-x);
add_edge(S3,i+n,INF,INF+x+y);
add_edge(S4,i+n,INF,INF+x-y);
}
memcpy(vhd,hd,sizeof(hd));
while(bfs())
while(dfs(0,INF));
printf("%lld",2LL*INF*s-ans);
return 0;
}

[AGC034D] Manhattan Max Matching的更多相关文章

  1. 【杂题】[AGC034D] Manhattan Max Matching【费用流】

    Description 有一个无限大的平面,有2N个位置上面有若干个球(可能重复),其中N个位置是红球,N个位置是蓝球,红球与蓝球的总数均为S. 给出2N个位置和上面的球数,现要将红球与蓝球完美匹配, ...

  2. @atcoder - AGC034D@ Manhattan Max Matching

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 考虑一个二维平面,执行共 2*N 次操作: 前 N 次,第 i ...

  3. [AGC034D]Manhattan Max Matching:费用流

    前置姿势 \(k\)维空间内两点曼哈顿距离中绝对值的处理 戳这里:[CF1093G]Multidimensional Queries 多路增广的费用流 据说这个东西叫做ZKW费用流? 流程其实很简单, ...

  4. 「AGC034D」 Manhattan Max Matching

    「AGC034D」 Manhattan Max Matching 传送门 不知道这个结论啊... (其实就是菜嘛) 首先 \(O(n^2)\) 的建边显然不太行. 曼哈顿距离有这样一个性质,如果将绝对 ...

  5. 【AtCoder】AGC034

    AGC034 刷了那么久AtCoder我发现自己还是只会ABCE(手动再见 A - Kenken Race 大意是一个横列,每个点可以跳一步或者跳两步,每个格子是空地或者石头,要求每一步不能走到石头或 ...

  6. [2019多校联考(Round 6 T3)]脱单计划 (费用流)

    [2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...

  7. CSS 3学习——transition 过渡

    以下内容根据官方规范翻译以及自己的理解整理. 1.介绍 这篇文档介绍能够实现隐式过渡的CSS新特性.文档中介绍的CSS新特性描述了CSS属性的值如何在给定的时间内平滑地从一个值变为另一个值. 2.过渡 ...

  8. 《算法》第六章部分程序 part 6

    ▶ 书中第六章部分程序,包括在加上自己补充的代码,包括二分图最大匹配(最小顶点覆盖)的交替路径算法和 HopcroftKarp 算法 ● 二分图最大匹配(最小顶点覆盖)的交替路径算法 package ...

  9. 最大流应用(Maximum Flow Application)

    1. 二分图匹配(Bipartite Matching) 1.1 匹配(Matching) Def. Given an undirected graph \(G = (V, E)\), subset ...

  10. 学习《Hardware-Efficient Bilateral Filtering for Stereo Matching》一文笔记。

    个人收藏了很多香港大学.香港科技大学以及香港中文大学里专门搞图像研究一些博士的个人网站,一般会不定期的浏览他们的作品,最近在看杨庆雄的网点时,发现他又写了一篇双边滤波的文章,并且配有源代码,于是下载下 ...

随机推荐

  1. 一个 Java 接口快速开发框架:magic-api

    一.简介 magic-api是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口.无需定义Controller.Service.Dao.Ma ...

  2. 通过API接口获取到数据后的使用方法以及储存方法

    API接口是许多应用程序和服务所必需的,可以将多个应用程序连接起来,允许不同应用程序之间的数据共享.在本文中,我们将探讨如何使用API接口获取数据,以及如何储存这些数据. 1.使用API接口获取数据 ...

  3. git + docker + docker-compose + Jenkins+Linux 自动化构建、部署、测试过程

    Jenkins三大概念: Job:即为任务 插件:maven构建项目.git拉取代码.ssh插件 工作空间:任务的存储空间,即为git代码的存储空间 开发者在本地开发,然后提交到 Source Res ...

  4. 上位机使用JS SerialPort进行串口通信, 包含开发环境搭建和完整示例代码

    在嵌入式开发中,我们经常需要使用上位机(PC)与一些电路模块进行通信, 用于获取一些传感器的数据,或者发送命令控制相应的电路模块.NodeJS目前支持使用SerialPort模块进行串口通信,本文主要 ...

  5. PivotGridControl自定义行数据的统计公式

    我们在使用PivotGridControl进行数据统计的时候,用时候需要在不同的行使用不同的汇总公式的情况,本文就是为了说明怎么实现此功能,如下图说明 数据源: 注意:此时数据列指定的SummaryT ...

  6. rnacos实现raft和类distro协议,支持集群部署

    1. rnacos 简介 rnacos是一个用rust实现的nacos服务. rnacos是一个轻量. 快速.稳定.高性能的服务:包含注册中心.配置中心.web管理控制台功能,支持单机.集群部署. r ...

  7. Solution -「GXOI / GZOI 2019」AND OR Sum

    Description Link. 给定一个 \(N \times N\) 的矩阵,她希望求出: 该矩阵的所有子矩阵的 \(\texttt{AND}\) 值之和(所有子矩阵 \(\texttt{AND ...

  8. POI 操作sheet.shiftRows注意点

    sheet.shiftRows后使用getRow/getCell会导致NullPointException 正确使用应该是CreateRow CreateCell

  9. 【遥遥领先】Eolink IDEA 插件:零代码入侵,自动生成接口

    省流版: Eolink 有 IDEA 插件吗? 有,而且遥遥领先!我们在一年半之前就发布了,而且功能更丰富! IDEA 插件市场搜索"Eolink Apikit"即可安装使用. 使 ...

  10. docker入门加实战——docker安装并配置阿里云加速

    docker入门加实战--docker安装并配置阿里云加速 为什么要学习docker 在开发和部署项目的过程中,经常会遇到如下问题: 软件安装包名字复杂,不知道去哪里找 安装软件和部署项目步骤复杂,容 ...