【bzoj4443】[Scoi2015]小凸玩矩阵
2016-04-07 21:54
267 查看
第K大也就是第n-K+1小,所以就可以的二分答案了 (江哥讲过一道类似题)
二分答案找出比当前答案小的数的位置的坐标,判断一下是否可以选出满足不在同一行同一列的n-K+1个数,然后就可以跑匈牙利了,对于一个坐标(x,y)如果满足a[x][y]≤a[x][y]当前答案,就把第x行向第y列连边,然后跑匈牙利判断最大匹配是否大于n-K+1
二分答案找出比当前答案小的数的位置的坐标,判断一下是否可以选出满足不在同一行同一列的n-K+1个数,然后就可以跑匈牙利了,对于一个坐标(x,y)如果满足a[x][y]≤a[x][y]当前答案,就把第x行向第y列连边,然后跑匈牙利判断最大匹配是否大于n-K+1
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<queue> #include<set> using namespace std; #define M 300 #define N 1000001 struct edge { int v,next; }e[N<<1]; int head[N<<1]; int cnt; int map[M][M]; int ly ,f ; int n,m,k; int l,r; int maxn,tot,ans; void link(int x,int y) { e[++cnt]=(edge){y,head[x]}; head[x]=cnt; } bool find(int d) { for (int i=head[d];i;i=e[i].next) { int t=e[i].v; if (ly[t]!=tot) { ly[t]=tot; if (!f[t] || find(f[t])) { f[t]=d; return true; } } } return false; } int work(int x) { ans=cnt=0; memset(head,0,sizeof(head)); memset(f,0,sizeof(f)); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (map[i][j]<=x) link(i,j); for (int i=1;i<=n;i++) { tot++; ans+=find(i); } return ans>=k ? 1: 0; } int main() { scanf("%d%d%d",&n,&m,&k); k=n-k+1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&map[i][j]),maxn=max(maxn,map[i][j]); l=1; r=maxn; while (l<r) { int m=l+r>>1; if (work(m)) r=m; else l=m+1; } printf("%d\n",l); return 0; }
相关文章推荐
- Windows内存小结
- Java中equals和==的区别
- wscript.shell
- 关于C语言的问卷调查
- 编程之美 - 1 的数目
- 七月算法机器学习笔记9 推荐系统
- MapReduce总结 (1)
- 35 个 Java 代码性能优化总结
- git常用命令
- php设计模式之适配器模式
- 【CodeForces】[658A]Bear and Reverse Radewoosh
- 如何坚持每周写一篇博客
- [Unity热更新]tolua# & LuaFramework(五):.proto转换为.lua
- python subprocess
- sed 基本使用
- 也许图像学习从此刻开始
- LIS最长上升子序列O(n^2)&O(nlogn)
- 好的架构不是设计出来的,而是演进出来的
- 刚学的网页换肤
- 解决PowerDesigner中DBMS有关的设置问题