前置姿势

\(k\)维空间内两点曼哈顿距离中绝对值的处理

戳这里:[CF1093G]Multidimensional Queries

多路增广的费用流

据说这个东西叫做ZKW费用流?

流程其实很简单,就是把EK中的单路回溯改成利用DFS多路增广,类似Dinic那样,可以看作是EK的一个优化。需要注意的是要标记从源点到当前点的路径,以免陷入零环无法自拔。

代码

bool spfa(){
memset(dis,0x3f,sizeof dis);
rin(i,1,n)cur[i]=head[i];
while(!q.empty())q.pop();
dis[s]=0,book[s]=true;q.push(s);
while(!q.empty()){
int x=q.front();q.pop();
trav(i,x){
int ver=e[i].to;
if(e[i].cap&&dis[ver]>dis[x]+e[i].cost){
dis[ver]=dis[x]+e[i].cost;
if(!book[ver]){
book[ver]=true;
q.push(ver);
}
}
}
book[x]=false;
}
return dis[t]<1e9;
} int dfs(int x,int pref){
if(x==t||!pref)return pref;
int temp=0,flow=0;insta[x]=true;
for(int &i=cur[x];i;i=e[i].nxt){
int ver=e[i].to;if(insta[ver])continue;
if(dis[ver]==dis[x]+e[i].cost&&(temp=dfs(ver,std::min(pref,e[i].cap)))){
e[i].cap-=temp;
e[i^1].cap+=temp;
flow+=temp;
pref-=temp;
mincost+=temp*e[i].cost;
if(!pref)break;
}
}
insta[x]=false;
return flow;
} void ek(){
while(spfa())maxflow+=dfs(s,1e9);
}

分析

显然费用流,直接建图的话每一对红球和蓝球(的位置)都需要连边,一共要连\(O(N^2)\)条边,再跑费用流的话显然时间爆炸。

注意到把绝对值拆开后\((x,y)\)系数只有\(2^2\)种可能性,并且两个球的距离是这四种情况中最大值,所以我们可以对四种情况分开处理,因为我们知道一对匹配的费用取的一定是最大值,即这两个球的距离。

具体如何建图可以参考代码。

代码

#include <bits/stdc++.h>

#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL; using std::cerr;
using std::endl; inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int MAXN=1005; int n,s,t,ecnt=1,head[MAXN<<1]; struct Edge{
int to,nxt,cap,cost;
}e[MAXN*20]; inline void add_edge(int bg,int ed,int ca,int co){
++ecnt;
e[ecnt].to=ed;
e[ecnt].nxt=head[bg];
e[ecnt].cap=ca;
e[ecnt].cost=co;
head[bg]=ecnt;
} int maxflow,cur[MAXN<<1];
LL mincost,dis[MAXN<<1];
bool book[MAXN<<1],insta[MAXN<<1];
std::queue<int> q; bool spfa(){
memset(dis,0x3f,sizeof dis);
rin(i,1,t)cur[i]=head[i];
while(!q.empty())q.pop();
dis[s]=0,book[s]=true;q.push(s);
while(!q.empty()){
int x=q.front();q.pop();
trav(i,x){
int ver=e[i].to;
if(e[i].cap&&dis[ver]>dis[x]+e[i].cost){
dis[ver]=dis[x]+e[i].cost;
if(!book[ver]){
book[ver]=true;
q.push(ver);
}
}
}
book[x]=false;
}
return dis[t]<1e18;
} int dfs(int x,int pref){
if(x==t||!pref)return pref;
int temp=0,flow=0;insta[x]=true;
for(int &i=cur[x];i;i=e[i].nxt){
int ver=e[i].to;if(insta[ver])continue;
if(dis[ver]==dis[x]+e[i].cost&&(temp=dfs(ver,std::min(pref,e[i].cap)))){
e[i].cap-=temp;
e[i^1].cap+=temp;
flow+=temp;
pref-=temp;
mincost+=1ll*temp*e[i].cost;
if(!pref)break;
}
}
insta[x]=false;
return flow;
} void ek(){
while(spfa())maxflow+=dfs(s,1e9);
} int main(){
n=read();
int x0=n*2+1,x1=x0+1,x2=x1+1,x3=x2+1;
s=x3+1,t=s+1;
rin(i,1,n){
int rx=read(),ry=read(),rc=read();
add_edge(s,i,rc,0);
add_edge(i,s,0,0);
add_edge(i,x0,1e9,rx+ry);
add_edge(x0,i,0,-rx-ry);
add_edge(i,x1,1e9,rx-ry);
add_edge(x1,i,0,-rx+ry);
add_edge(i,x2,1e9,-rx+ry);
add_edge(x2,i,0,rx-ry);
add_edge(i,x3,1e9,-rx-ry);
add_edge(x3,i,0,rx+ry);
}
rin(i,1,n){
int bx=read(),by=read(),bc=read();
add_edge(n+i,t,bc,0);
add_edge(t,n+i,0,0);
add_edge(x0,n+i,1e9,-bx-by);
add_edge(n+i,x0,0,bx+by);
add_edge(x1,n+i,1e9,-bx+by);
add_edge(n+i,x1,0,bx-by);
add_edge(x2,n+i,1e9,bx-by);
add_edge(n+i,x2,0,-bx+by);
add_edge(x3,n+i,1e9,bx+by);
add_edge(n+i,x3,0,-bx-by);
}
ek();
printf("%lld\n",-mincost);
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

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

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

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

  5. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  6. 洛谷 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 ...

  7. bzoj4514: [Sdoi2016]数字配对--费用流

    看了一眼题目&数据范围,觉得应该是带下界的费用流 原来想拆点变成二分图,能配对的连边,跑二分图,可行性未知 后来看到另外一种解法.. 符合匹配要求的数要满足:质因子的个数相差为1,且两者可整除 ...

  8. BZOJ-3130 费用流 (听题目胡扯丶裸最大流) 二分判定+最大流+实数精度乱搞

    DCrusher爷喜欢A我做的水题,没办法,只能A他做不动的题了.... 3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec ...

  9. 【TYVJ】1982 武器分配(费用流)

    http://tyvj.cn/Problem_Show.aspx?id=1982 一眼题.. 源向每个人连容量为1,费用为0的边. 每个人向一个中转节点na连容量1,费用0的边(你也可以不连,直接连后 ...

随机推荐

  1. NOIP2012 D2T3 疫情控制 题解

    题面 这道题由于问最大值最小,所以很容易想到二分,但怎么验证并且如何实现是这道题的难点: 首先我们考虑,对于一个军队,尽可能的往根节点走(但一定不到)是最优的: 判断一个军队最远走到哪可以树上倍增来实 ...

  2. Eslint报错整理与解决方法

    1.‘Unexpected tab character’ 字面意思理解呢就是意想不到的制表符,当时出现的时候就是我习惯的使用Tab键去打空格,但是eslint默认不认可Tab,所以解决方法很简单: 在 ...

  3. leecode刷题(31) -- 回文数

    leecode刷题(31) -- 回文数 回文数 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输 ...

  4. eclipse+maven搭建springboot项目入门

    一.下载jdk,例如(jdk1.8.171) 安装(注意仅仅安装jdk就可以了,不要安装jre,设置JAVA_HOME,配置jdk环境变量) 二.下载maven(apache-maven-3.5.3- ...

  5. python+minicap的使用

    说起Minicap,不得不提到STF,STF (Smartphone Test Farm) 是一个开源的web架构应用,用户可通过浏览器远程操作Android设备.调试Android应用.在设备上进行 ...

  6. Git 一般性操作

    git全局设定 git config --global user.name “码云账号” git config --global user.email “码云注册邮箱” git 定位文件夹cd进入到需 ...

  7. O019、通过例子学习 Keystone

    参考https://www.cnblogs.com/CloudMan6/p/5373311.html   上节介绍了 Keystone 的核心概念.本节我们通过“查询可用 image”这个操作让大家对 ...

  8. 自己实现JDK动态代理

    实验的目录结构 1.JDK动态代理 先来一段jdk动态代理的demo,首先创建一个接口,Person public interface Person { public void eat(); } 实现 ...

  9. 使用redislive监控redis

    redis监控工具redislive的安装 1. pip安装 如果主机没有pip先安装pip工具 wget --no-check-certificate https://github.com/pypa ...

  10. react 中 css模块化类名 和普通全局类名 一起使用

    <div className={[`${styles.tableOpers}`,`clearfix`].join(' ')}></div>