bzoj4443[SCOI2015]小凸玩矩阵
题意:一个n*m的矩阵(n<=m<=250),要求选出n个数(每行,每列最多选一个),求第k大数的最小值。
首先第k大的意思是从大到小的第k个数(我读错了,WA了一次还以为算法不对...)
然后第k大最小不好直接做.考虑二分答案.
二分答案的单调性在于,如果不能选出n-k+1个小于等于i的不同行列的数,那么最终的答案大于i,否则最终的答案小于等于i。
判定的时候将每一行看作一个点,每一列也看作一个点,每个位置A[i][j](A[i][j]小于等于判定的答案ans)代表一条第i行和第j行之间的边。(这种二维矩阵每一行怎么样怎么样每一列怎么样怎么样的题常常可以转化成二分图去考虑)。
最后二分出一个i,使得我们可以选出n-k+1个小于等于i的数但不能选出n-k+1个小于等于(i-1)的数,这个i就是答案.
这里有一点问题,就是我们虽然可以选出n-k+1个小于等于i的数,但似乎并没有保证可以选出k-1个大于i的数.因此我在读错题WA了一发之后开始怀疑算法正确性。
所幸,随便选出剩下k-1个数一定可以保证第k大的数字是i.
证明如下:
首先,我们选出所有数字之后,不可能选出n-k+1个小于等于(i-1)的数(否则与二分的结果相违背)。也就是说,我们在选出n-k+1个小于等于i的数之后,随便选剩下的k-1个数字,最终选出的全部数字中至少有k个大于等于i.
于是我们有两个条件:全部数字中,至少有n-k+1个小于等于i(二分条件保证可以先选出n-k+1个这样的数,这个条件等价于从小到大第n-k+1个数也就是从大到小第k个数一定小于等于i),至少有k个大于等于i(也就是说从大到小第k个数一定大于等于i),那么第k大的数既小于等于i又大于等于i,所以第k大的数只能是i,这样就没有问题了。
(似乎别人的题解都觉得这是显然的)
(写了个dinic结果比别人的匈牙利慢好多)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
int n,m,k;
int a[maxn][maxn];
struct edge{
int to,next,w;
}lst[maxn*maxn*];int len=,first[maxn*],_first[maxn*];
void addedge(int a,int b,int w){
lst[len].to=b;lst[len].next=first[a];lst[len].w=w;first[a]=len++;
lst[len].to=a;lst[len].next=first[b];lst[len].w=;first[b]=len++;
}
int s,t;
int q[maxn*],vis[maxn*],T,dis[maxn*],head,tail;
bool bfs(){
vis[s]=++T;head=tail=;
q[tail++]=s;dis[s]=;
while(head!=tail){
int x=q[head++];
for(int pt=first[x];pt!=-;pt=lst[pt].next){
if(lst[pt].w&&vis[lst[pt].to]!=T){
vis[lst[pt].to]=T;dis[lst[pt].to]=dis[x]+;
q[tail++]=lst[pt].to;
}
}
}
if(vis[t]==T)memcpy(_first,first,sizeof(first));
return vis[t]==T;
}
int dfs(int x,int lim){
if(x==t)return lim;
int flow=,a;
for(int pt=_first[x];pt!=-;pt=lst[pt].next){
_first[x]=pt;
if(lst[pt].w&&dis[lst[pt].to]==dis[x]+&&(a=dfs(lst[pt].to,min(lst[pt].w,lim-flow)))){
lst[pt].w-=a;lst[pt^].w+=a;flow+=a;
if(flow==lim)break;
}
}
return flow;
}
int dinic(){
int ans=,x;
while(bfs())
while(x=dfs(s,0x7f7f7f7f))ans+=x;
return ans;
}
bool check(int ans){
memset(first,-,sizeof(first));len=;
s=;t=n+m+;
for(int i=;i<=n;++i){
addedge(s,i,);
}
for(int i=;i<=m;++i){
addedge(n+i,t,);
}
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
if(a[i][j]<=ans)addedge(i,n+j,);
}
}
return dinic()>=k;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
k=n-k+;
for(int i=;i<=n;++i){
for(int j=;j<=m;++j){
scanf("%d",&a[i][j]);
}
}
int l=,r=;
while(l<=r){
int mid=(l+r)>>;
if(check(mid)){
r=mid-;
}else{
l=mid+;
}
}
printf("%d\n",r+);
return ;
}
bzoj4443[SCOI2015]小凸玩矩阵的更多相关文章
- 2018.06.30 BZOJ4443: [Scoi2015]小凸玩矩阵(二分加二分图匹配)
4443: [Scoi2015]小凸玩矩阵 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N< ...
- bzoj4443 SCOI2015 小凸玩矩阵 matrix
传送门:bzoj4443 题解 很水的一道网络流,显然可以二分答案,然后我们希望第\(k\)大尽量小,那么对于一个\(mid\),我们应尽量选择更小的,然后跑二分图最大匹配来验证. code
- 【BZOJ4443】[Scoi2015]小凸玩矩阵 二分+二分图最大匹配
[BZOJ4443][Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或 ...
- BZOJ_4443_[Scoi2015]小凸玩矩阵_二分+二分图匹配
BZOJ_4443_[Scoi2015]小凸玩矩阵_二分+二分图匹配 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个 ...
- 【BZOJ4443】小凸玩矩阵(二分答案,二分图匹配)
[BZOJ4443]小凸玩矩阵(二分答案,二分图匹配) 题面 BZOJ Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两 ...
- BZOJ 4443: [Scoi2015]小凸玩矩阵 最大流
4443: [Scoi2015]小凸玩矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Description 小凸和小方是好 ...
- bzoj 4443 [Scoi2015]小凸玩矩阵 网络流,二分
[Scoi2015]小凸玩矩阵 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1564 Solved: 734[Submit][Status][Di ...
- 【bzoj4443】【[Scoi2015]小凸玩矩阵】二分+二分图最大匹配
(上不了p站我要死了,侵权度娘背锅) Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸 ...
- [bzoj4443] [loj#2006] [洛谷P4251] [Scoi2015]小凸玩矩阵
Description 小凸和小方是好朋友,小方给小凸一个 \(N \times M\)( \(N \leq M\) )的矩阵 \(A\) ,要求小秃从其中选出 \(N\) 个数,其中任意两个数字不能 ...
随机推荐
- MongoDB基础命令笔记
一.创建数据库 use foobar 二.创建集合 db.persons.insert({name:"zhaomin",age:23}) 三.查找 db.persons.find( ...
- BPM实例分享——金额规则大写
金额规则大写 在涉及金额的流程中经常会遇到需要大写金额数据与小写金额匹配,如何实现输入数字后自动转换呢? 初级用法: 1.在默认表单基本属性javascript 中增加如下金额转换方法 /** 数字金 ...
- RMI(远程接口调用)
1. RMI的原理: RMI系统结构,在客户端和服务器端都有几层结构. 方法调用从客户对象经占位程序(Stub).远程引用层(Remote Reference Layer)和传输层(Transport ...
- Project Server 2016 部署
问题: 手动创建网站集后,激活Project的功能时候报错 Only Administrator users can obtain the connection string for [Admin] ...
- iOS之UI组件整理
作者:神兽gcc 授权本站转载. 最近把iOS里的UI组件重新整理了一遍,简单来看一下常用的组件以及它们的实现.其实现在这些组件都可以通过Storyboard很快的生成,只是要向这些组件能够变得生动起 ...
- 安装cocoapods遇到两大坑-Ruby版本升级和Podfile的配置
今天安装cocoapods #移除原有ruby源 $ gem sources --remove https://rubygems.org/ #使用可用的淘宝网 $ gem sources -a htt ...
- MyBatis中jdbcType和javaType的映射关系
JDBC Type Java Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIM ...
- response和request的区别以及常见问题解决
request是请求,即客服端发来的请求 response是响应,是服务器做出的响应 --------------------------------------------------------- ...
- text-overflow
text-overflow:clip | ellipsis 默认值:clip 适用于:所有元素 clip: 当对象内文本溢出时不显示省略标记(...),而是将溢出的部分裁切掉. ellipsis: 当 ...
- reborn to freelancer
I want to be a freelancer, so I come back to record all my efforts. I hope this will be a new start ...