解法是匈牙利+二分
但是不知道为什么WA on 7,9,10
希望佬们能指出问题,或给出hack数据
#include <bits/stdc++.h>
using namespace std;
const int Maxn = 20005;
struct edge
{
int to, nxt;
} e[Maxn << 1];
int tot = -1, head[Maxn];
void add(int u, int v)
{
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
}
int n, m, match[Maxn], a[Maxn][Maxn], que[Maxn], k, pos;
bool st[Maxn];
bool find(int u)
{
for (int i = head[u]; ~i; i = e[i].nxt)
{
int v = e[i].to;
if (st[v])
continue;
st[v] = 1;
if (!match[v] || find(match[v]))
{
match[v] = u;
return true;
}
}
return false;
}
bool check(int x)
{
int ans = 0;
tot = -1;
memset(head, -1, sizeof(head));
memset(match, 0, sizeof(match));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (a[i][j] <= que[x])
add(i, j);
}
}
for (int i = 1; i <= n; i++)
{
memset(st, 0, sizeof(st));
if (find(i))
ans++;
}
if (ans > n - k)
return true;
else
return false;
}
int main()
{
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
que[(i - 1) * m + j] = a[i][j];
}
sort(que + 1, que + 1 + n * m);
int l = 1, r = n * m;
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid))
pos = que[mid], r = mid - 1;
else
l = mid + 1;
}
cout << pos;
return 0;
}