# [二分][匈牙利算法] Bzoj P4443 小凸玩矩阵

3 4 2
1 5 6 6
8 3 4 3
6 8 6 3

3

## HINT

1<=K<=N<=M<=250,1<=矩阵元素<=10^9

# 题解

• 二分答案转化为判定性问题
• 设二分的答案为mid，用二分图匹配来求最多能选出多少个不大于mid的数即可

# 代码

 1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 using namespace std;
6 struct edge {int to,from;}e[100000];
8 bool dfs(int x)
9 {
11         if (!vis[e[i].to])
12         {
13             vis[e[i].to]=1;
14             if (!p[e[i].to]||dfs(p[e[i].to])) { p[e[i].to]=x; return 1; }
15         }
16     return 0;
17 }
18 bool check(int x)
19 {
21     for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (a[i][j]<=x) add(i,j);
22     memset(p,0,sizeof(p));
23     for (int i=1;i<=n;i++)
24     {
25         memset(vis,0,sizeof(vis));
26         if (dfs(i)) num++;
27     }
28     return num>n-k;
29 }
30 int main()
31 {
32     scanf("%d%d%d",&n,&m,&k);
33     for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&a[i][j]),l=min(l,a[i][j]),r=max(r,a[i][j]);
34     while (l<=r)
35     {
36         int mid=l+r>>1;
37         if (check(mid)) ans=mid,r=mid-1; else l=mid+1;
38     }
39     printf("%d",ans);
40 }

posted @ 2019-07-09 15:30  BEYang_Z  阅读(...)  评论(...编辑  收藏