【题解】Ples [COCI2011]

依旧是没有传送门,只有提供了数据官网

【题目描述】

\(N\) 个汉子和 \(N\) 个妹纸一起参加舞会,跳舞时只能是一个汉子一个妹纸配对,现在给出每个人的身高,任意一个人都只想和比 \(\text{ta}\) 高(矮)的人跳,身高一样的人都不想与对方跳。输出满足人们愿望的前提下可组成的最多对数。.

【输入】

第一行一个数 \(N\) 表示汉子和妹纸的个数。

第二行 \(N\) 个整数,其绝对值表示 \(N\) 个汉子的身高 \(h\),\(h\) 为正数表示他想与比自己高的人跳,负数则相反。

第三行 \(N\) 个整数,表示妹纸,其它与第二行相同。

【输出】

一个数,表示组成的最多对数。.

【样例】

样例输入:
1
-1800
1800 样例输出:
0 样例输入:
1
1700
-1800 样例输出:
1 样例输入:
2
-1800 -2200
1900 1700 样例输出:
2

【数据范围】

\(100 \%:\) \(1 \leqslant N \leqslant 100000,\) \(1500 \leqslant h[i] \leqslant 2500\)


【分析】

乍一看:我 \(c\),开局就上送分板子题。

恩恩?不对不对,光是建图就要体验 \(n\) 方卡百万。

再一看:\([1500,2500]\) 迅速发现了隐藏数据范围 \(h \leqslant 1000\),反手就是一个网络流

这应该是 \(\text{COCI2011}\) 写起来最爽的一道题了吧。。。不过正解貌似是贪心。

由于本题只关注相对大小,可以把输入的每个 \(h\) 都减去 \(1500\) 再加 \(1\),映射到 \([1,1001]\) 里面去,然后记录在每一种身高下汉子、妹纸的个数。

\(A[h][1]\) 表示高度为 \(h\) 且想要配偶比自己高的汉子数量,

\(A[h][0]\) 表示高度为 \(h\) 且想要配偶比自己矮的汉子数量;

\(B[h][1]\) 表示高度为 \(h\) 且想要配偶比自己高的妹纸数量,

\(B[h][0]\) 表示高度为 \(h\) 且想要配偶比自己矮的妹纸数量。

对每个高度建四个点,分别表示上述加黑字体的四种人,超源连向所有汉子,妹纸连向所有超汇,容量设为人种数量。

\(1001^2\) 枚举所有高度配对:

对于 \(h_i>h_j\),\(0\) 汉子与 \(1\) 妹纸连一条容量为 \(min(A[h_i][0],B[h_j][1])\) 的边。

对于 \(h_i<h_j\),\(1\) 汉子与 \(0\) 妹纸连一条容量为 \(min(A[h_i][1],B[h_j][0])\) 的边。

然后随便背个最大流板子就 \(ok\) 啦。

建边数量为:\((1001^2+1001*4)*2=1006005*2\) 。


【Code】

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#define Re register int
using namespace std;
const int N=4050,M=1006050,inf=2e9;
int n,x,o=1,T,st,ed,maxflow,A[N>>2][2],B[N>>2][2],head[N];
struct QAQ{int to,next,flow;}a[M<<1];
inline void add_(Re x,Re y,Re flow){a[++o].flow=flow,a[o].to=y,a[o].next=head[x],head[x]=o;}
inline void add(Re x,Re y,Re flow){add_(x,y,flow),add_(y,x,0);}
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
int h,t,Q[N],cur[N],dis[N];
inline int bfs(Re st,Re ed){
for(Re i=0;i<=ed;++i)cur[i]=head[i],dis[i]=0;
h=1,t=0,dis[st]=1,Q[++t]=st;
while(h<=t){
Re x=Q[h++],to;
for(Re i=head[x];i;i=a[i].next)
if(a[i].flow&&!dis[to=a[i].to]){
dis[to]=dis[x]+1,Q[++t]=to;
if(to==ed)return 1;
}
}
return 0;
}
inline int dfs(Re x,Re flow){
if(!flow||x==ed)return flow;
Re tmp=0,to,f;
for(Re i=cur[x];i;i=a[i].next){
cur[x]=i;
if(dis[to=a[i].to]==dis[x]+1&&(f=dfs(to,min(flow-tmp,a[i].flow)))){
a[i].flow-=f,a[i^1].flow+=f,tmp+=f;
if(tmp==flow)break;
}
}
return tmp;
}
inline void Dinic(Re st,Re ed){while(bfs(st,ed))maxflow+=dfs(st,inf);}
int main(){
// freopen("ples.in","r",stdin);
// freopen("ples.out","w",stdout);
in(T),n=1001,st=n<<2|1,ed=st+1;
for(Re i=1;i<=T;++i){
in(x);
if(x>0)++A[x-1500+1][1];//汉子想要妹纸比自己高
else ++A[-x-1500+1][0];//汉子想要妹纸比自己矮
}
for(Re i=1;i<=T;++i){
in(x);
if(x>0)++B[x-1500+1][1];//妹纸想要汉子比自己高
else ++B[-x-1500+1][0];//妹纸想要汉子比自己矮
}
for(Re i=1;i<=n;++i){//超源连汉子
if(A[i][0])add(st,i,A[i][0]);
if(A[i][1])add(st,i+n,A[i][1]);
}
for(Re i=1;i<=n;++i){//妹纸连超汇
if(B[i][0])add(i+(n<<1),ed,B[i][0]);
if(B[i][1])add(i+(n<<1)+n,ed,B[i][1]);
}
for(Re i=1;i<=n;++i){//汉子连妹纸
if(A[i][0])
for(Re j=1;j<i;++j)
if(B[j][1])add(i,j+(n<<1)+n,min(A[i][0],B[j][1]));//必须要两厢情愿才连边
if(A[i][1])
for(Re j=i+1;j<=n;++j)
if(B[j][0])add(i+n,j+(n<<1),min(A[i][1],B[j][0]));
}
Dinic(st,ed);
printf("%d\n",maxflow);
fclose(stdin);
fclose(stdout);
return 0;
}

【题解】Ples [COCI2011]的更多相关文章

  1. 【题解】Dvoniz [COCI2011]

    [题解]Dvoniz [COCI2011] 没有传送门,只有提供了数据的官网. [题目描述] 对于一个长度为 \(2*K\) 的序列,如果它的前 \(K\) 个元素之和小于等于 \(S\) 且后 \( ...

  2. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  3. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  4. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  5. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  6. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  7. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  8. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  9. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

随机推荐

  1. antV G2 为柱状图添加背景颜色

    工作中需要在基础柱状图的基础上添加一个自定义高度的背景颜色, 基础柱状图: 目标柱状图: 由于chart绘图可以重叠,通过该特性,我们可以在画两次图重叠在一起,第一次绘图描述背景,第二次绘图描述数据, ...

  2. wpf 两个自定义控件

    wpf 两个自定义控件 一个是IP控件,一个滑动条.先看下效果图 IPControl 1.实际工作中有时需要设置IP信息,就想着做一个ip控件.效果没有window自带的好,需要通过tab切换.但也能 ...

  3. PHP通过session判断防止表单重复提交实例

    PHP通过session判断防止表单重复提交实例,当用户提交表单后,为防止重复操作,通过session来判断是否为初次提交,否则让他返回到之前表单页面. 当前表单页面is_submit设为0 SESS ...

  4. Flask--请求扩展

    目录 请求扩展 before_request after_request before_first_request teardown_request errorhandler template_glo ...

  5. 2.java容器的设计模式

    目录 1.collection接口中的迭代器模式 2.迭代器模式 1.collection接口中的迭代器模式 迭代器分析: Iterator接口有hasNext().next(),remove()三个 ...

  6. 使用maven-compiler-plugin以及maven-shade-plugin完成maven项目打包

    最近负责一个纯maven项目(项目需求尽量轻量化),需要自己完成打包工作. 因此,基于maven-compiler-plugin以及maven-shade-plugin完成项目的打包工作. 其中: m ...

  7. linux scp命令 将数据从一台linux服务器复制到另一台linux服务器

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  8. Kettle 执行SQL脚本

    以下操作都在5.0.1版本下进行开发,其余版本可以进行自动比对 本文将对Kettle5中常用步骤字段选择(又名选择/改名值,英文原名:Select Values)进行详细解释.这个步骤的功能非常强大, ...

  9. OpenGL实例:纹理映射

    OpenGL实例:纹理映射 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:计算机图形学 1. 介绍 用于指定一维.二维和三维纹理的函数分别 ...

  10. hibernate之主键生成策略

    1. hibernate的主键生成器: generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 . 连接数据库的xml hibernate.cfg.xml <?xml ...