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

题目链接:

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

题解:

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

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 
 7 const int maxn=255;
 8 const int INF=1e9;
 9 int mat[maxn][maxn];
10 
11 int n,m,k;
12 int lef[maxn],_t[maxn];
13 vector<int> G[maxn];
14 
15 bool match(int i){
16     for(int j=0;j<G[i].size();j++){
17         int v=G[i][j];
18         if(_t[v]==0){
19             _t[v]=1;
20             if(!lef[v]||match(lef[v])){
21                 lef[v]=i;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28 
29 bool check(int x){
30     for(int i=1;i<=n;i++) G[i].clear();
31     memset(lef,0,sizeof(lef));
32     for(int i=1;i<=n;i++){
33         for(int j=1;j<=m;j++){
34             if(mat[i][j]<=x) G[i].push_back(j);
35         } 
36     }
37     for(int i=1;i<=n;i++){
38         memset(_t,0,sizeof(_t));
39         match(i); 
40     }
41     int cnt=0;
42     for(int i=1;i<=m;i++){
43         if(lef[i]) cnt++; 
44     } 
45     if(cnt>=n-k+1) return true;
46     return false;
47 }
48 
49 int main(){
50     while(scanf("%d%d%d",&n,&m,&k)==3&&n){
51         for(int i=1;i<=n;i++){
52             for(int j=1;j<=m;j++){
53                 scanf("%d",&mat[i][j]);
54             } 
55         } 
56         int low=0,hig=INF;
57         while(low<hig-1){
58             int mid=low+(hig-low)/2;
59             if(check(mid)) hig=mid;
60             else low=mid;
61         }
62         printf("%d\n",hig);
63     }
64     return 0;
65 } 

 

posted @ 2016-05-24 15:42  fenicnn  阅读(175)  评论(0编辑  收藏  举报