您的位置:首页 > 其它

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

2016-05-24 15:42 555 查看

题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=4443

题解:

二分答案,判断最大匹配是否>=n-k+1;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;

const int maxn=255;
const int INF=1e9;
int mat[maxn][maxn];

int n,m,k;
int lef[maxn],_t[maxn];
vector<int> G[maxn];

bool match(int i){
for(int j=0;j<G[i].size();j++){
int v=G[i][j];
if(_t[v]==0){
_t[v]=1;
if(!lef[v]||match(lef[v])){
lef[v]=i;
return true;
}
}
}
return false;
}

bool check(int x){
for(int i=1;i<=n;i++) G[i].clear();
memset(lef,0,sizeof(lef));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mat[i][j]<=x) G[i].push_back(j);
}
}
for(int i=1;i<=n;i++){
memset(_t,0,sizeof(_t));
match(i);
}
int cnt=0;
for(int i=1;i<=m;i++){
if(lef[i]) cnt++;
}
if(cnt>=n-k+1) return true;
return false;
}

int main(){
while(scanf("%d%d%d",&n,&m,&k)==3&&n){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&mat[i][j]);
}
}
int low=0,hig=INF;
while(low<hig-1){
int mid=low+(hig-low)/2;
if(check(mid)) hig=mid;
else low=mid;
}
printf("%d\n",hig);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: