bzoj 4443: [Scoi2015]小凸玩矩阵
2016-05-15 11:46
417 查看
4443: [Scoi2015]小凸玩矩阵
Description
小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少。Input
第一行给出三个整数N,M,K接下来N行,每行M个数字,用来描述这个矩阵
Output
如题Sample Input
3 4 21 5 6 6
8 3 4 3
6 8 6 3
Sample Output
3HINT
1<=K<=N<=M<=250,1<=矩阵元素<=10^9ACTY真大神!!!(大家有空去bzoj上搜搜看)
—————以下题解——————
很容易看出是二分答案。。
题目中说是第k大,其实是第n-k+1小(一直看错)。。。
我们每次验证mid时把矩阵中<=mid的数关于坐标连边,跑一遍二分图最大匹配,判断最大匹配数是否大于n-k+1。。
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; const int N=255; int n,m,k,i,j,ans,a ,f ,p ; int tot,head ,Next[N*N],to[N*N]; void add(int x,int y) { tot++; to[tot]=y; Next[tot]=head[x]; head[x]=tot; } int dfs(int x,int T) { int i; for(i=head[x];i!=-1;i=Next[i]) if(p[to[i]]!=T) { int y=to[i]; p[y]=T; if(f[y]==0||dfs(f[y],T)) { f[y]=x; return 1; } } return 0; } int erfen(int l,int r) { if(l>r) return l; int mid=(l+r)>>1,i,j,ans=0; tot=0; for(i=1;i<=n;i++) head[i]=-1; for(i=1;i<=m;i++) p[i]=f[i]=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(a[i][j]<=mid) add(i,j); for(i=1;i<=n;i++) ans+=dfs(i,i); if(ans>=n-k+1) return erfen(l,mid-1);else return erfen(mid+1,r); } int main() { scanf("%d%d%d",&n,&m,&k); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); ans=max(ans,a[i][j]); } cout<<erfen(1,ans); return 0; }
相关文章推荐
- Codeforces Gym 100971M Decomposition into Good Strings DP+数据结构
- I2C总线协议
- vim粘贴复制学习
- 第八周项目一(1)-数组做数据成员
- Pyqt print输出到控件中小demo
- bzoj 2243 染色
- centos6一键安装lnmp+zabbix服务端
- 安卓入门--Activity跳转页面
- nginx的配置文件详细说明
- python练习五—简单web应用
- ListView滑动删除效果实现
- 二叉树几种遍历算法的非递归实现
- C++基础之宏的使用
- 吴恩达机器学习笔记_第五周
- C++设计模式浅识单例模式
- 相见恨晚:linux下的c++filt 命令
- Oracle字符集与字符类型存储空间占用
- common lisp 安装和使用第三方包
- 打开网站php出现乱码问题的解决办法以及无法显示验证码
- 初步掌握Yarn的架构及原理