Description

有一个无限大的平面,有2N个位置上面有若干个球(可能重复),其中N个位置是红球,N个位置是蓝球,红球与蓝球的总数均为S。

给出2N个位置和上面的球数,现要将红球与蓝球完美匹配,匹配的权值是每一对匹配两个球的位置坐标的曼哈顿距离之和。

求最大权值。

N<=1000,每个位置上球数<=10,坐标非负且<=10^9

Solution

直接两两连边显然不行

但又不能对于每一个球单独计算贡献,因为绝对值的存在

考虑这样一个转化

|x1-x2|=max(x1-x2,x2-x1)

|x1-x2|+|y1-y2|=max(x1-x2+y1-y2,x2-x1+y1-y2,x1-x2+y2-y1,x2-x1+y2-y1)

我们额外建4个中转点表示上面的四种情况,红球和蓝球通过中转点连边,这样边数降到了O(N)

边权就按照上面四种情况的符号连,容量为1,跑最大费用最大流。

由于最大费用最大流的性质,保证了每个匹配都是最大的,因此恰好就是曼哈顿距离取了绝对值符号后的结果。

时间复杂度O(maxflow(N))

Code

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
const int N=2115;
const int INF=1e7;
typedef long long LL;
using namespace std;
vector <int> ap[N];
int n,n1,st,ed,f[N][N];
LL ans,pr[N][N];
void link(int x,int y,int w,LL c)
{
ap[x].push_back(y);
f[x][y]=w,pr[x][y]=c;
ap[y].push_back(x);
f[y][x]=0,pr[y][x]=-c;
}
typedef vector<int>::iterator IT;
namespace Flow
{
LL dis[N];
bool bz[N];
IT cur[N];
int d[200*N];
bool spfa()
{
memset(dis,107,sizeof(dis));
memset(bz,0,sizeof(bz));
dis[st]=0,bz[st]=1,d[1]=st;
fo(i,1,n1) cur[i]=ap[i].begin();
int l=0,r=1;
while(l<r)
{
int k=d[++l];
for(IT i=ap[k].begin();i!=ap[k].end();i++)
{
int p=*i;
if(f[k][p]&&dis[k]+pr[k][p]<dis[p])
{
dis[p]=dis[k]+pr[k][p];
if(!bz[p]) bz[p]=1,d[++r]=p;
}
}
bz[k]=0;
}
return (dis[ed]<=1e17);
}
int flow(int k,int s)
{
if(k==ed) return s;
int sl=0,v;
bz[k]=1;
for(;cur[k]!=ap[k].end();cur[k]++)
{
int p=*cur[k];
if(!bz[p]&&f[k][p]&&dis[p]==dis[k]+pr[k][p])
{
if(v=flow(p,min(s,f[k][p])))
{
sl+=v,s-=v;
f[k][p]-=v,f[p][k]+=v;
ans+=(LL)v*pr[k][p];
if(!s) break;
}
}
}
bz[k]=0;
return sl;
}
}
using Flow::flow;
using Flow::spfa;
int main()
{
cin>>n;
n1=2*n+6,st=2*n+5,ed=n1;
fo(i,1,n)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
link(st,i,z,0);
link(i,2*n+1,z,x+y);
link(i,2*n+2,z,x-y);
link(i,2*n+3,z,-x+y);
link(i,2*n+4,z,-x-y);
}
fo(i,1,n)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
link(i+n,ed,z,0);
link(2*n+1,i+n,z,-x-y);
link(2*n+2,i+n,z,-x+y);
link(2*n+3,i+n,z,x-y);
link(2*n+4,i+n,z,x+y);
}
ans=0;
while(spfa())
flow(st,INF);
printf("%lld\n",-ans);
}

【杂题】[AGC034D] Manhattan Max Matching【费用流】的更多相关文章

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

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

  2. @atcoder - AGC034D@ Manhattan Max Matching

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

  3. 「AGC034D」 Manhattan Max Matching

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

  4. 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)

    传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...

  5. 2018.10.15 loj#6013. 「网络流 24 题」负载平衡(费用流)

    传送门 费用流sb题. 直接从sss向每个点连边,容量为现有物品量. 然后从ttt向每个点连边,容量为最后库存量. 由于两个点之间可以互相任意运送物品,因此相邻的直接连infinfinf的边就行了. ...

  6. 【Codevs1237&网络流24题餐巾计划】(费用流)

    题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 ...

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

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

  8. CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)

    题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...

  9. [NOI2012]美食节(费用流)

    题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...

随机推荐

  1. Ubuntu - Ubuntu应用记录(1)

    1.发生dpkg status database is locked by another process 原因是包管理器没有正确关闭.需要重启计算机或者重新打开终端 输入: sudo rm /var ...

  2. 结合docker做flask+kafka数据接口与压力测试

    一.需求 需要做实时数据接入的接口.数据最终要写入库,要做到高并发,数据的完整,不丢失数据. 二.技术选型 1.因为只是做简单的接口,不需要复杂功能,所以决定用flask这个简单的python框架(因 ...

  3. Linux-1.1root初始密码设置,切换root用户

    Ubuntu安装好后,root密码需要自己设置 root初始密码设置 sudo passwd root 权限不够时,切换root su 回车后输入密码 exit 退出登录的账户

  4. 编译LNMP部署动态网站环境

    LNMP动态网站部署架构是由一套 Linux+Nginx+MySQL+PHP 组成的动态网站系统解决方案. 以下配置环境为:Linux=RHEL7 --> Nginx=1.13 --> M ...

  5. Buy a Ticket CodeForces - 938D (dijkstra)

    大意: n节点无向图, 点$i$到点$j$的花费为$2dis(i,j)+a[j]$, 对于每个点, 求最少花费. 每条边权翻倍, 源点S向所有点$i$连边, 权为$a[i]$, 答案就为$S$到每个点 ...

  6. python网络爬虫(3)python爬虫遇到的各种问题(python版本、进程等)

    import urllib2 源地址 在python3.3里面,用urllib.request代替urllib2 import urllib.request as urllib2 import coo ...

  7. C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编

    函数重写:(在子类中重写父类中的函数) 父类中被重写的函数  依然会继承  给子类. 子类中重写的函数将覆盖父类中的函数. 通过作用域分辨符  ::  可以访问到父类中的函数. 例如: #includ ...

  8. 禁止缩放meta标签

    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale= ...

  9. Gcc 安装过程中部分配置

    Gcc 安装过程中部分配置详解 全文参考<have fun with Gcc>一文,如有需要请联系原作者prolj@163.com 解压gcc源码后,需要进行configure,这时候一般 ...

  10. 给定一个字符串,根据字符出现频率排序--Java实现

    题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列. 示例 1: 输入:"tree" 输出:"eert" 解释:'e'出现两次,'r'和't' ...