【题解】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. MySQL的5大引擎及优劣之分

    MySQL提供了多个不同的存储引擎,其中5大引擎有:innodb,myisam,memory,merge,csv. 其中优点有:灾难恢复性好.支持事务.使用行级锁.支持外键关联.支持热备份 缺点如下: ...

  2. PHP mysqli_rollback MySQLi 函数

    定义和用法 mysqli_rollback - 回退当前事务 语法: mysqli_rollback ( mysqli $link ) 参数 参数 必需的 描述 link 是 由mysqli_conn ...

  3. arcgis api for javascript 学习(二) 发布并调用地图切片

    文章将从发布切片地图到调用切片地图整个过程都展示出来. (一).切片地图的发布 1.还是前面的arcgis展示的地图 2.与发布动态地图前面的步骤是一样的 打开分享后,如图 3.一切就绪后,到达缓存的 ...

  4. 实验吧简单的SQL注入1,简单的SQL注入

    接上面一篇博客. 实验吧简单的sql注入1 题目连接   http://ctf5.shiyanbar.com/423/web/ 同样,直接输入 1加个但引号,结果下面有返回错误,            ...

  5. 判断map是否包含另一个map

    判断map是否包含另一个map: map不同与list集合,list集合有直接判断集合是否包含其他集合或者元素的方法. boolean contains(Object o) 如果list包含指定的元素 ...

  6. web前端学习路线(干货)

  7. ACM-ICPC 2018 焦作网络赛

    题目顺序:A F G H I K L 做题链接 A. Magic Mirror 题意:判断 给出的 字符串 是否等于"jessie",需要判断大小写 题解:1.用stl库 tolo ...

  8. poppler

    https://github.com/freedesktop/poppler http://www.openjpeg.org/ https://github.com/uclouvain/openjpe ...

  9. 28道java基础面试题-下

    28道java基础面试题下 15.Java语言如何进行异常处理,关键字:throws.throw.try.catch.finally分别如何使用? 答:Java通过面向对象的方法进行异常处理,把各种不 ...

  10. Django2.2报错 AttributeError: 'str' object has no attribute 'decode'

    准备将 Django 连接到 MySQL,在命令行输入命令 python manage.py makemigrations 后报错: AttributeError: 'str' object has ...