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. 如何让WPF中的ValidationRule实现参数绑定

    背景 应用开发过程中,常常会对用户输入内容进行验证,通常是基于类型.范围.格式或者特定的要求进行验证,以确保输入符合预期.例如邮箱输入框校验输入内容是否符合邮箱格式.在WPF中,数据模型允许将Vali ...

  2. TCP的可靠性之道:确认重传和流量控制

    TCP 全称为 Transmission Control Protocol(传输控制协议),是一种面向连接的.可靠的.基于字节流的传输层通信协议,其中可靠性是相对于其他传输协议的优势点.TCP 为了确 ...

  3. CopyOnWriteArrayList 写时复制思想

    写时复制 conpyOnWrite容器即写时复制容器.往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy,复制出一个新的容器Object[] ...

  4. SQL函数升序Asc,降序Desc使用总结

    关键字-升序Asc及降序Desc的使用语法 对某一结果集按列进行升序或降序排列即:结果集 Order by 列名/数字 Asc/Desc. 一.Asc,Desc排序讲以下5点 1.不写关键字Asc/D ...

  5. Java 深度优先搜索 and 广度优先搜索的算法原理和代码展示

    111. 二叉树的最小深度 题目:给定一个二叉树,找出其最小深度.最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明:叶子节点是指没有子节点的节点. 方法1:深度优先搜索 原理:深度优先搜 ...

  6. oauth2单点登录集成

    单点登陆 概念: 单点登录其实就是在多个系统之间建立链接, 打通登录系统, 让同一个账号在多个系统中通用 举个例子: 登录Gmail的时候可以用账号密码登录, 也可以用google账号登录, 而使用g ...

  7. python包引用方式总结

    本文为博主原创,转载请注明出处: 在Python中,有多种引用包的方式.以下是常见的方式: 1. import语句 import语句是最常见和推荐的引用包的方式.它允许你引入整个包或包中的特定模块/子 ...

  8. 为zabbix穿上一件漂亮的外衣

    zabbix+Grafana 7.0  zabbix的环境已部署好的情况下,zabbix部分-- 略 Grafana简介: 1.Grafana自身并存储数据,数据从其它地方获取.需要配置数据源 2.G ...

  9. 关于虚拟机的IP地址经常改变问题的解法

    主要解法就是配置静态IP地址 首先了解一下IP和子网掩码,网关的含义:IP 是标识计算机特定地址的二进制数,子网掩码用于和IP组合划分子网;网关是将信息传送到网关进行收发 开始配置:首先打开Linux ...

  10. Python 数学函数和 math 模块指南

    Python 提供了一组内置的数学函数,包括一个广泛的数学模块,可以让您对数字执行数学任务. 内置数学函数.min() 和 max() 函数可用于在可迭代对象中查找最低或最高值: 示例:查找可迭代对象 ...