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

题面

你是一家相亲机构的策划总监,在一次相亲活动中,有 n 个小区的若干男士和 n个小区的若干女士报名了这次活动,你需要将这些参与者两两匹配(只能男生和 女生相匹配),每个小区都提供了自己的地址,用二维平面上的坐标(x,y)来表示,若 A 男所在小区的地址为(x1,y1),B 女所在小区的地址为(x2,y2),由“距离产生美”可得,A 男不 B 女匹配的亲密值为他们的曼哈顿距离|x1-x2|+|y1-y2|,现在要求你确定一种匹配方案使得总亲密值最大(每位男士只能匹配一位女士,每位女士也只能匹配一位男士)

分析

此题和[AGC 034D]Manhattan Max Matching几乎一模一样

小区之间两两连容量无穷,费用为两点间曼哈顿距离的边,原点到男士所在小区连容量为该小区男士数量,费用为0的边。女士所在小区到汇点同理。这样显然是会超时的。

考虑简化的情况,如果费用为\(x_1-x_2+y_1-y_2\),那么可以建一个辅助点u,\((x_1,y_1)\)男士对应的点向u连费用为\(x_1+y_1\)的边,u向女士\((x_2,y_2)\)连费用为\(-x_2-y_2\)的边。跑费用流的时候费用叠加,就得到了\(x_1-x_2+y_1-y_2\)。这样连边的边数是\(O(n)\)的

有绝对值符号怎么办。把绝对值按符号拆成4种情况。\(|x_1-x_2|+|y_1-y_2|=max(x_1-x_2+y_1-y_2,x_2-x_1+y_1-y_2,x_1-x_2+y_2-y_1,x_2-x_1+y_2-y_1)\)

建4个辅助点对应4种情况,每个点都像上面那样连边。

由于是最大费用,跑出来的是4种情况最大值,恰好就是曼哈顿距离取了绝对值符号后的结果。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cstdlib>
#include<queue>
#define INF 0x3f3f3f3f3f3f3f3f
#define maxn 10000
#define maxm 3000000
using namespace std;
typedef long long ll;
int n,m;
inline void qread(int& x){
x=0;
int sign=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') sign=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
x=x*sign;
}
inline void qread(ll& x){
x=0;
int sign=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') sign=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
x=x*sign;
} struct node{
ll x;
ll y;
int c;
}a[maxn+5],b[maxn+5]; inline ll get_dist(node p,node q){
return abs(p.x-q.x)+abs(p.y-q.y);
} namespace network_flow{
struct edge{
int from;
int to;
int next;
ll flow;
ll cost;
}E[maxm+5];
int head[maxn+5];
int sz=1;
void add_edge(int u,int v,ll w,ll c){
#ifdef DEBUG
// printf("%d->%d vol=%lld cost=%lld\n",u,v,w,c);
#endif
c=-c;
sz++;
E[sz].from=u;
E[sz].to=v;
E[sz].flow=w;
E[sz].cost=c;
E[sz].next=head[u];
head[u]=sz;
sz++;
E[sz].from=v;
E[sz].to=u;
E[sz].flow=0;
E[sz].cost=-c;
E[sz].next=head[v];
head[v]=sz;
} bool inq[maxn+5];
int pre[maxn+5];
ll minf[maxn+5];
ll dist[maxn+5];
bool spfa(int s,int t){
for(int i=s;i<=t;i++){
inq[i]=0;
pre[i]=0;
dist[i]=INF;
minf[i]=INF;
}
queue<int>q;
q.push(s);
inq[s]=1;
dist[s]=0;
while(!q.empty()){
int x=q.front();
q.pop();
inq[x]=0;
for(int i=head[x];i;i=E[i].next){
int y=E[i].to;
if(E[i].flow&&dist[y]>dist[x]+E[i].cost){
dist[y]=dist[x]+E[i].cost;
pre[y]=i;
minf[y]=min(minf[x],E[i].flow);
if(!inq[y]){
q.push(y);
inq[y]=1;
}
}
}
}
return dist[t]!=INF;
}
void update(int s,int t){
int x=t;
while(x!=s){
int i=pre[x];
E[i].flow-=minf[t];
E[i^1].flow+=minf[t];
x=E[i].from;
}
}
ll mcmf(int s,int t){ ll flow=0,cost=0;
while(spfa(s,t)){
flow+=minf[t];
cost+=minf[t]*dist[t];
update(s,t);
}
return -cost;
}
void solve(){
int s=0,t=n*2+5;
int p1=n*2+1,p2=n*2+2,p3=n*2+3,p4=n*2+4;
for(int i=1;i<=n;i++){
add_edge(s,i,a[i].c,0);
}
for(int i=1;i<=n;i++){
add_edge(i+n,t,b[i].c,0);
}
//绝对值分符号拆成4个,用4个辅助点连边
//因为是最大费用,4种情况取最大值就是绝对值
//这样就把边数从O(n^2)变成O(n)
for(int i=1;i<=n;i++){
//x1-x2+y1-y2
add_edge(i,p1,INF,a[i].x+a[i].y);
add_edge(p1,i+n,INF,-b[i].x-b[i].y);
//x1-x2+y2-y1
add_edge(i,p2,INF,a[i].x-a[i].y);
add_edge(p2,i+n,INF,-b[i].x+b[i].y);
//x2-x1+y1-y2
add_edge(i,p3,INF,-a[i].x+a[i].y);
add_edge(p3,i+n,INF,b[i].x-b[i].y);
//x2-x1+y2-y1
add_edge(i,p4,INF,-a[i].x-a[i].y);
add_edge(p4,i+n,INF,b[i].x+b[i].y);
}
printf("%lld\n",mcmf(s,t));
}
} int main(){
// freopen("1.in","r",stdin);
qread(n);
for(int i=1;i<=n;i++){
qread(a[i].x);
qread(a[i].y);
qread(a[i].c);
}
for(int i=1;i<=n;i++){
qread(b[i].x);
qread(b[i].y);
qread(b[i].c);
}
network_flow::solve();
}

[2019多校联考(Round 6 T3)]脱单计划 (费用流)的更多相关文章

  1. [多校联考2019(Round 5 T3)]青青草原的表彰大会(dp+组合数学)

    [多校联考2019(Round 5)]青青草原的表彰大会(dp+组合数学) 题面 青青草原上有n 只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献 ...

  2. [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)

    [多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...

  3. [多校联考2019(Round 5 T2)]蓝精灵的请求(二分图染色+背包)

    [多校联考2019(Round 5)]蓝精灵的请求(二分图染色+背包) 题面 在山的那边海的那边住着 n 个蓝精灵,这 n 个蓝精灵之间有 m 对好友关系,现在蓝精灵们想要玩一个团队竞技游戏,需要分为 ...

  4. 三校联考 Day3

    三校联考 Day3 大水题 题目描述:给出一个圆及圆上的若干个点,问两个点间的最远距离. solution 按极角排序,按顺序枚举,显然距离最远的点是单调的,线性时间可解出答案. 大包子的束缚 题目描 ...

  5. 【赛时总结】NOIP2018-三校联考1024

    ◇NOIP三校联考-1024◇ 发现以前的博客写得似乎都很水……基本上都没什么阅读量QwQ 决定改过自新╰( ̄ω ̄o) 就从这篇博客开始吧~ 现场考得无地自容,看到题解才发现一些东西……(我第三题还没 ...

  6. 【五校联考1day2】JZOJ2020年8月12日提高组T2 我想大声告诉你

    [五校联考1day2]JZOJ2020年8月12日提高组T2 我想大声告诉你 题目 Description 因为小Y 是知名的白富美,所以自然也有很多的追求者,这一天这些追求者打算进行一次游戏来踢出一 ...

  7. 【五校联考1day2】JZOJ2020年8月12日提高组T1 对你的爱深不见底

    [五校联考1day2]JZOJ2020年8月12日提高组T1 对你的爱深不见底 题目 Description 出乎意料的是,幸运E 的小R 居然赢了那个游戏.现在欣喜万分的小R 想要写一张明信片给小Y ...

  8. 2019十二省联考 Round 1 && 济南市市中心游记

    在这样一场毒瘤的省选中 这道题目无疑是命题人无私的馈赠 大量精心构造的部分分,涵盖了题目中所有涉及的算法 你可以利用这道题目,对你是否能够进入省队进行初步检查 经典的模型.较低的难度和不大的代码量,能 ...

  9. [2017/5/28]FJ四校联考

    来自FallDream的博客,未经允许,请勿转载,谢谢. 话说这一段时间算是过去了,好久好久之后终于又有联考了  没想到这次到我们学校出题,昨天才想起来,临时花一天赶了一套,我出了一个sbFFT,质量 ...

随机推荐

  1. UVa 213 信息解码 (模拟 && 二进制)

    题意 :对于下面这个字符串 0,00,01,10,000,001,010,011……. 首先是长度为1的串,然后是长度为2的串,以此类推.不存在全为1的串. 你的任务是编写一个程序.首先输入一个代码头 ...

  2. LSTM细节

    为什么使用tanh? 为了克服梯度消失问题,我们需要一个二阶导数在趋近零点之前能维持很长距离的函数.tanh是具有这种属性的合适的函数. 为什么要使用Sigmoid? 由于Sigmoid函数可以输出0 ...

  3. Mysql安装及用简单用法

    Mysql安装和初始化 初见: Mysql软件 - 服务端软件 - 服务端程序 - 解析指令 - 对文件的操作 - 客户端软件 - 客户端程序 - 发送指令(sql语句) - 解析指令 其他类似软件: ...

  4. 南昌网络赛 H The Nth Item

    南昌网络赛The Nth Item 暴力快速幂+unordered_map记忆化 注意:记忆化不能写到快速幂求解函数里,不断调用函数会造成很大的时间浪费 #include<bits/stdc++ ...

  5. spring 接口校验参数(自定义注解)

    1. 注解类 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.l ...

  6. mysql 安装相关

    Mysql 是基于C/S端的管理文件的服务器软件. Mysql简单分为两个软件:1服务器软件 2客户端软件 对于服务器软件中的socket服务器是一只开着的,客户端需要连接,并且还有创建文件删除文件等 ...

  7. 【机器学习速成宝典】模型篇02线性回归【LR】(Python版)

    目录 什么是线性回归 最小二乘法 一元线性回归 多元线性回归 什么是规范化 Python代码(sklearn库) 什么是线性回归(Linear regression) 引例 假设某地区租房价格只与房屋 ...

  8. 在VSCode中开启ESLint风格审查

    最近一直在学习开发一个VUE项目,几乎没有前端基础摸爬滚打,就一边摸索HTML,JS,CSS一边模仿着已有代码开发,也还算能学到东西. VSCode确实还不错,很轻量.在刚开始学写vue的时候,后台总 ...

  9. 【奇技淫巧】linux 定时任务 crontab 反弹 shell

    日期:2018-11-26 13:47:34 介绍:如何使用定时任务来反弹 shell? 0x01. 基本命令 参数 -e:编辑该用户的计时器设置: -l:列出该用户的计时器设置: -r:删除该用户的 ...

  10. 中国MOOC_零基础学Java语言_第2周 判断_1时间换算

    第2周编程题 查看帮助 返回   第2周编程题 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截 ...