【题解】Ples [COCI2011]
【题解】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]的更多相关文章
- 【题解】Dvoniz [COCI2011]
[题解]Dvoniz [COCI2011] 没有传送门,只有提供了数据的官网. [题目描述] 对于一个长度为 \(2*K\) 的序列,如果它的前 \(K\) 个元素之和小于等于 \(S\) 且后 \( ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
随机推荐
- 玩下PHP的分词,最近有这个需求
找了个地方 下载代码 我是在这里下载的 https://www.jb51.net/codes/65593.html 1 下载完毕后 打开是这样的文件 2 先把代码集成到thinkphp3.2.3里 ...
- int[]里数的个数怎么由输入决定?-----动态数组。
java中如何创建动态数组?(摘自百度知道) Java动态数组是一种可以任意伸缩数组长度的对象,在Java中比较常用的是ArrayList,ArrayList是javaAPI中自带的java.util ...
- Feign自动装配原理
spring.factories 按照以往的惯例,在研究源码的时候,我们先看一下spring.factories文件下自动装配的类FeignAutoConfiguration,其中比较重要的东西有这么 ...
- Python上下文管理器的使用
上下文管理器可以控制代码块执行前的准备动作,以及执行后的清理动作. 创建一个上下文管理器类的步骤:(1)一个__init__方法,来完成初始化(可选)(2)一个__enter__方法,来完成所有建立工 ...
- [20190524]sqlplus 与输出&.txt
[20190524]sqlplus 与输出&.txt --//在sqlplus下 &一般作为参数替换,如何要输出&,一般有几种情况.据说这个问题是asktom站点查看最多的问题 ...
- Pycharm 2019 添加 docker 解释器
打开docker的tls
- Python的运用基础3
1. 简述执行Python程序的两种方式以及他们的优缺点? 交互式(jupyter) 优点:运行一句执行一句 缺点:关闭即消失 ==例如== win10系统cmd窗口 命令行式(Pycharm) 优点 ...
- 201871010111-刘佳华《面向对象程序设计(java)》第十一周学习总结
201871010111-刘佳华<面向对象程序设计(java)>第十一周学习总结 实验九 泛型程序设计技术 实验时间 2019-11-8 1.实验目的与要求 (1) 理解泛型概念: (2 ...
- Jmeter请求
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web=& ...
- day51_9_15_Django
一.pycharm接受网页信息原理. 如何实现在后端接受浏览器的数据,并解析出有用的信息呢? 使用socket编写网络连接,然后通过浏览器访问ip+端口号. import socket def ind ...