Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 149  Solved: 81
[Submit][Status][Discuss]

Description

小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少。

Input

第一行给出三个整数N,M,K
接下来N行,每行M个数字,用来描述这个矩阵

Output

如题 

Sample Input

3 4 2
1 5 6 6
8 3 4 3
6 8 6 3

Sample Output

3

HINT

1<=K<=N<=M<=250,1<=矩阵元素<=10^9

题解:

  N个数中的第K大,就是第N-K+1小,这点要是没看见就毁了。设这个数为x,二分这个数,判断是否合法。

  判断合法的方法,N^2枚举矩阵中的每个数,如果这个a[i][j]数小于等于x,让i连一条到j,容量为1的边。因为要保证N个数的i,j各不相同,所以设行i为x集,列j为y集,所有边权均为1,做最大流,也就是二分图的最大匹配。如果跑出来的maxflow大于等于N-K+1,说明x满足条件。注意以上两个不等关系都是大于等于,因为要考虑这样一种情况,整个矩阵的数字都是1,第1小是1,第N小还是1。我被这个坑了好久。。。

 /**************************************************************
Problem: 4443
User: __abcdef__
Language: C++
Result: Accepted
Time:216 ms
Memory:14640 kb
****************************************************************/ #include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
const int inf=1e9,maxn=;
int N,M,K,S,T,tot,MIN=inf,MAX;
int a[maxn][maxn],tmp[maxn][maxn];
struct MAT{
int x,y,v,f;
}mat[maxn*maxn];
inline int cmp(const MAT & e,const MAT & w){
return e.v<w.v;
} struct Edge{
int to,rest,next;
}e[maxn*maxn*];
int head[maxn*maxn],cnt=;
inline void Addedge(int x,int y,int r){
e[++cnt].to=y; e[cnt].rest=r; e[cnt].next=head[x]; head[x]=cnt;
e[++cnt].to=x; e[cnt].rest=; e[cnt].next=head[y]; head[y]=cnt;
} int dis[maxn*maxn];
inline bool BFS(){
memset(dis,,sizeof(dis));
static queue<int> Q;
while(!Q.empty()) Q.pop();
Q.push(S); dis[S]=;
while(!Q.empty()){
int x=Q.front(); Q.pop();
for(int i=head[x];i;i=e[i].next){
int y=e[i].to;
if(dis[y]==&&e[i].rest){
dis[y]=dis[x]+;
Q.push(y);
}
}
}
if(dis[T]!=) return true;
return false;
}
inline int DFS(int x,int flow){
if(x==T) return flow;
int now=,temp;
for(int i=head[x];i;i=e[i].next){
int y=e[i].to;
if(dis[y]==dis[x]+&&e[i].rest){
temp=DFS(y,min(flow-now,e[i].rest));
e[i].rest-=temp;
e[i^].rest+=temp;
now+=temp;
if(now==flow) return flow;
}
}
if(!now) dis[x]=;
return now;
} inline int dinic(){
int ans=;
while(BFS()==true) ans+=DFS(S,inf);
return ans;
} inline bool jud(int x){ for(int i=;i<=cnt+;i++) e[i].to=e[i].rest=e[i].next=;
memset(head,,sizeof(head)); cnt=;
S=; T=N+M+;
for(int i=;i<=N;i++) Addedge(S,i,);// S 连向 x集 权值为 1
for(int i=;i<=M;i++) Addedge(N+i,T,);//y集 连向 T 权值为 1
for(int i=;i<=N;i++){// x集 连向 y集
for(int j=;j<=M;j++){
if(tmp[i][j]<=x){
Addedge(i,N+j,);
}
}
}
int maxflow=dinic();
if(maxflow>=N-K+) return true;
else return false;
}
inline int find(int l,int r){
if(l+>=r){
if(jud(l)==true) return l;
else return r;
}
int mid=(l+r)>>;
if(jud(mid)==true) return find(l,mid);
else return find(mid+,r);
}
int main(){
scanf("%d%d%d",&N,&M,&K);
for(int i=;i<=N;i++){
for(int j=;j<=M;j++){
scanf("%d",&a[i][j]);
mat[++tot].x=i; mat[tot].y=j; mat[tot].v=a[i][j];
}
}
tot=;
sort(mat+,mat+N*M+,cmp);
for(int i=;i<=N*M;i++){
if(mat[i].v!=mat[i-].v) mat[i].f=++tot;
else mat[i].f=tot;
}
for(int i=;i<=N*M;i++){
tmp[mat[i].x][mat[i].y]=mat[i].f;
MIN=min(MIN,mat[i].f); MAX=max(MAX,mat[i].f);
}
int ggg=find(MIN,MAX);
for(int i=;i<=N;i++){
for(int j=;j<=M;j++){
if(tmp[i][j]==ggg){
printf("%d\n",a[i][j]);
return ;
}
}
}
return ;
}

bzoj 4443: [Scoi2015]小凸玩矩阵的更多相关文章

  1. BZOJ 4443: [Scoi2015]小凸玩矩阵 最大流

    4443: [Scoi2015]小凸玩矩阵 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4443 Description 小凸和小方是好 ...

  2. bzoj 4443 [Scoi2015]小凸玩矩阵 网络流,二分

    [Scoi2015]小凸玩矩阵 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1564  Solved: 734[Submit][Status][Di ...

  3. 【刷题】BZOJ 4443 [Scoi2015]小凸玩矩阵

    Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最 ...

  4. BZOJ 4443 [Scoi2015]小凸玩矩阵(二分答案+二分图匹配)

    [题目链接]http://www.lydsy.com/JudgeOnline/problem.php?id=4443 [题目大意] 从矩阵中选出N个数,其中任意两个数字不能在同一行或同一列 求选出来的 ...

  5. BZOJ 4443: [Scoi2015]小凸玩矩阵 二分图最大匹配+二分

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4443 题解: 二分答案,判断最大匹配是否>=n-k+1: #include< ...

  6. 2018.06.30 BZOJ4443: [Scoi2015]小凸玩矩阵(二分加二分图匹配)

    4443: [Scoi2015]小凸玩矩阵 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方是好朋友,小方给小凸一个N*M(N< ...

  7. BZOJ_4443_[Scoi2015]小凸玩矩阵_二分+二分图匹配

    BZOJ_4443_[Scoi2015]小凸玩矩阵_二分+二分图匹配 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个 ...

  8. 【BZOJ4443】[Scoi2015]小凸玩矩阵 二分+二分图最大匹配

    [BZOJ4443][Scoi2015]小凸玩矩阵 Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或 ...

  9. 图论(网络流):[SCOI2015]小凸玩矩阵

    Description 小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最 ...

随机推荐

  1. Suricata开源IDS安装与配置

    开源IDS Suricata安装 Linux下的依赖问题的解决 在Debian,Ubuntu或者Linux Mint系列 $ sudo apt-get install wget build-essen ...

  2. 【BZOJ4236】JOIOJI STL

    [BZOJ4236]JOIOJI Description JOIOJI桑是JOI君的叔叔.“JOIOJI”这个名字是由“J.O.I”三个字母各两个构成的. 最近,JOIOJI桑有了一个孩子.JOIOJ ...

  3. 解读 Android TTS 语音合成播报

    随着从事 Android 开发年限增加,负责的工作项目也从应用层开发逐步过渡到 Android Framework 层开发.虽然一开始就知道 Android 知识体系的庞大,但是当你逐渐从 Appli ...

  4. map容器结构体离散化

    小数坐标离散化: #include"string.h" #include"stdio.h" #include"iostream" #incl ...

  5. Linux系列-Xshell连接本地VMware安装的Linux虚拟机

    一.安装VMwareWorkstation并安装RedHat虚拟机,这里安装步骤省略,网络的资料很多,大侠们不如百度或者谷歌一下,大把的资料. 二.打开本地电脑的“网络连接”,你会发现多出了2个网络适 ...

  6. java利用poi 把ppt转化为图片,

    导入jar包: poi-3.8.jar poi-ooxml-3.9.jar poi-scratchpad-3.8.jar 代码: package test4; import java.awt.Dime ...

  7. 性能分析工具gprof介绍(转载)

    性能分析工具gprof介绍Ver:1.0 目录1. GPROF介绍 42. 使用步骤 43. 使用举例 43.1 测试环境 43.2 测试代码 43.3 数据分析 53.3.1 flat profil ...

  8. CMDB经验分享之 – 剖析CMDB的设计过程

    作为IT管理的核心,CMDB逐渐成为系统管理项目实施的热点.在很多的案例中,由于忽视了CMDB的因素,ITIL的深入应用受到了极大的挑战.同时,由于CMDB是IT管理信息的集中,CMDB也是一个重要的 ...

  9. HTTP返回码中301与302的区别(转)

    add by zhj:  区别 1.使用效果不同 302跳转是暂时的跳转,搜索引擎会抓取新的内容而保留旧的网址.因为服务器返回302代码,搜索引擎认为新的网址只是暂时的. 301重定向是永久的重定向, ...

  10. mysql int 整数类型 解释显示宽度 和 存储宽度

    存储宽度 是实际存储记录宽度 存储宽度默认是写死的,就算修改宽度也改变不了,改变的是显示宽度 ============有符号和无符号int============= 创建一个 无符号的 int 整数类 ...