传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4443
自招报名顺带在机房里写了写题
非常怀疑这个做法的正确性 不过还是写了
首先真的满足二分性质吗?
如果某些情况是不可能有解的
比如
2 2 2
1 4
3 2
如果二分到2,
也就是要选一个<=2 和一个>2的
此时根本无法选出满足条件
那么此时该向上还是向下二分……?
虽然还是得到了正确的结果……
把二分判定能否取到n-k+1个<=mid改成判定能够取到k个>=mid的就wa了……
还是觉得有问题……
算了不管了……上大学再说
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=255;
int a[255][255];
int n,m,k;
int mp[maxn][maxn];
int vis[maxn],Link[maxn];
int find(int u){
for(int i=1;i<=m;i++){
int v=i;
if(!mp[u][v]||vis[v]) continue;
vis[v]=1;
if(!Link[v]||find(Link[v])){Link[v]=u;return 1;}
}return 0;
}
bool check(int M){
memset(mp,0,sizeof mp);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j]<=M)
mp[i][j]=1;
memset(Link,0,sizeof Link);
int ans=0;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
if(find(i))ans++;
}
return ans>=n-k+1;
}
int main(){
scanf("%d%d%d",&n,&m,&k);
int mx=0;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&a[i][j]),mx=max(mx,a[i][j]);
int l=0,r=mx;
while(l<r){
int mid=(l+r)/2;
if(check(mid))
r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}