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( ...
- 商业智能软件对比评测:FineBI和Tableau
FineBI和Tableau是比较好的自助式商业智能软件,功能都很强大,是企业数据可视化不可或缺的利器,但两款产品还是有非常大的区别的,例如Tableau的功能全面且深入,更适合专业的数据分析人员,而 ...
- Android 内存泄漏的一些情况。
最近在维护代码,发现一个自定义View(这个View是在一个AsyncTask的工作线程doInBackground中新建的,在UI线程onPostExecute中添加进window中的)经常会泄漏内 ...
- [Android]异步 layout inflation(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5829809.html 异步 layout inflation ...
- React Native之 Navigator与NavigatorIOS使用
前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会有所 ...
- jquery 元素控制(追加元素/追加内容)
参考网址:http://www.jquerycn.cn/a_5521 一.在元素内部/外部追加元素 append,prepend:添加到子元素 before,after:作为兄弟元素添加 html: ...
- Python学习笔记3-字符串
格式化字符串/复合字段名 >>> import humansize >>> si_suffixes = humansize.SUFFIXES[1000] >& ...
- Mysql查询语句使用select.. for update导致的数据库死锁分析
近期有一个业务需求,多台机器需要同时从Mysql一个表里查询数据并做后续业务逻辑,为了防止多台机器同时拿到一样的数据,每台机器需要在获取时锁住获取数据的数据段,保证多台机器不拿到相同的数据. 我们My ...
- ajax 允许跨域html头设置
"Access-Control-Allow-Origin"= "*" "Access-Control-Allow-Headers"= &qu ...
- 同步降压DC-DC转换IC——XC9264
设计一个12V转3.3V,输出电流30mA的电源电路,由于项目对转化效率要求较高,所以不能采用低压差线性稳压LDO的方案.经过对比,TOREX的XC9264效率在此转化条件下效率可做到85%以上,比M ...