【杂题】[AGC034D] Manhattan Max Matching【费用流】
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【费用流】的更多相关文章
- [AGC034D]Manhattan Max Matching:费用流
前置姿势 \(k\)维空间内两点曼哈顿距离中绝对值的处理 戳这里:[CF1093G]Multidimensional Queries 多路增广的费用流 据说这个东西叫做ZKW费用流? 流程其实很简单, ...
- @atcoder - AGC034D@ Manhattan Max Matching
目录 @description@ @solution@ @accepted code@ @details@ @description@ 考虑一个二维平面,执行共 2*N 次操作: 前 N 次,第 i ...
- 「AGC034D」 Manhattan Max Matching
「AGC034D」 Manhattan Max Matching 传送门 不知道这个结论啊... (其实就是菜嘛) 首先 \(O(n^2)\) 的建边显然不太行. 曼哈顿距离有这样一个性质,如果将绝对 ...
- 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)
传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...
- 2018.10.15 loj#6013. 「网络流 24 题」负载平衡(费用流)
传送门 费用流sb题. 直接从sss向每个点连边,容量为现有物品量. 然后从ttt向每个点连边,容量为最后库存量. 由于两个点之间可以互相任意运送物品,因此相邻的直接连infinfinf的边就行了. ...
- 【Codevs1237&网络流24题餐巾计划】(费用流)
题意:一个餐厅在相继的 N 天里,每天需用的餐巾数不尽相同. 假设第 i 天需要 ri块餐巾(i=1,2,…,N).餐厅可以购买新的餐巾,每块餐巾的费用为 p 分: 或者把旧餐巾送到快洗部,洗一块需 ...
- [2019多校联考(Round 6 T3)]脱单计划 (费用流)
[2019多校联考(Round 6 T3)]脱单计划 (费用流) 题面 你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两 ...
- CF 277E Binary Tree on Plane (拆点 + 费用流) (KM也可做)
题目大意: 平面上有n个点,两两不同.现在给出二叉树的定义,要求树边一定是从上指向下,即从y坐标大的点指向小的点,并且每个结点至多有两个儿子.现在让你求给出的这些点是否能构成一棵二叉树,如果能,使二叉 ...
- [NOI2012]美食节(费用流)
题目描述 CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节.作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴.他很快就尝遍了美食节所有的美食.然而,尝鲜的欲望是难以满足的.尽管所有的菜品都 ...
随机推荐
- Go语言中的切片(十)
go中数组的长度是固定的,且不同长度的数组是不同类型,这样的限制带来不少局限性.于是切片就来了,切片(Slice)是一个拥有相同类型元素的可变长度的序列.它是基于数组类型做的一层封装.它非常灵活,支持 ...
- Java中对象和引用的理解
偶然想起Java中对象和引用的基本概念,为了加深下对此的理解和认识,特地整理一下相关的知识点,通过具体实例从两者的概念和区别两方面去更形象的认识理解,再去记忆. 一.对象和引用的概念: 在Java中万 ...
- Codeforces 1178D. Prime Graph
传送门 首先每个点至少要有两条边连接 那么容易想到先保证这一点然后再慢慢加边 那么先构成一个环即可:$(1,2),(2,3),(3,4)...(n,1)$ 然后考虑加边,发现一个点加一条边还是合法的, ...
- Makoto and a Blackboard CodeForces - 1097D (积性函数dp)
大意: 初始一个数字$n$, 每次操作随机变为$n$的一个因子, 求$k$次操作后的期望值. 设$n$经过$k$次操作后期望为$f_k(n)$. 就有$f_0(n)=n$, $f_k(n)=\frac ...
- ELK电子书籍
Elasticsearch in Action(英文版).pdfElasticsearch实战 in action(中文版).pdfElasticsearch技术解析与实战.pdfElasticsea ...
- QuickSort(快排)的JAVA实现
QuickSort的JAVA实现 这是一篇算法课程的复习笔记 用JAVA对快排又实现了一遍. 先实现的是那个easy版的,每次选的排序轴都是数组的最后一个: package com.algorithm ...
- MySQL中自定义排序
在开发时候,我们经常使用的是默认的排序规则,但在某些特殊情况下,通过指定顺序来进行排序 -- fileld自定义排序时,应该是非主键的,否则主键是无效 SELECT * FROM customer W ...
- 多线程编程-- part5.1 互斥锁之非公平锁-获取与释放
非公平锁之获取锁 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在“尝试获取锁的机制不同”.简单点说,“公平锁”在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而 ...
- Ansible-Playbook实战
一.Playbook 实战案例 1.准备环境 角色 外网IP(NAT) 内网IP(LAN) 部署软件 m01 eth0:10.0.0.61 eth1:172.16.1.61 ansible ly-ba ...
- openstack云主机冷迁移
1:开启nova计算节点之间互信 冷迁移需要nova计算节点之间使用nova用户互相免密码访问 默认nova用户禁止登陆,开启所有计算节点的nova用户登录shell. usermod -s /bin ...