链接:
http://exam.upc.edu.cn/problem.php?id=4199
题目:
题目描述
NEUACM team holds summer training every year. This year n students participate in the training, and we provide m computers. Everyone has a suitability (0<=suitability<=1000) to every computer. Now our coach needs to draw up a plan, which satisfies: 1. every student uses one computer, and a computer can be used by no more than one student; 2. maximize the minimum suitability, which means if the answer is w, then everyone’s suitability to his computer shouldn’t be less than w.
Hint: huge input, please use fast IO.
输入
The first line contains n and m (1<=n<=m<=500), indicating the number of students and computers.
Next n lines describes every student’s suitability to every computer, number in ith line and jth row means student[i]’s suitability to computer[j].
输出
A single number w in one line, which is described before.
样例输入
1 2 1 10 2 3 10 1 2 2 1 1
样例输出
10 2
题意:
给你一个
n×m
的图mp,
mp[i][j]
代表第i个学生对第j台电脑的适配程度,每台电脑只能由一个人使用,问在所有人都有电脑用的情况下,所有人里对当前电脑的适配值的最小的那个人的适配值的最大值。
思路:
直接二分答案,也就是每个人可以成功适配的最小适配值,不断让这个值增大,直到无法完成二分图匹配。
实现:
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <iomanip>
#include <functional>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#define edl putchar('\n')
#define ll long long
#define clr(a,b) memset(a,b,sizeof a)
#define rep(i,m,n) for(int i=m ; i<=n ; i++)
#define fep(i,n) for(int i=0 ; i<n ; i++)
namespace FastIO {
const int SIZE =
1 <<
16;
char buf[SIZE], obuf[SIZE], str[
60];
int bi = SIZE, bn = SIZE, opt;
int read(
char *s) {
while (bn) {
for (; bi < bn && buf[bi] <=
' '; bi++);
if (bi < bn)
break;
bn = fread(buf,
1, SIZE, stdin);
bi =
0;
}
int sn =
0;
while (bn) {
for (; bi < bn && buf[bi] >
' '; bi++) s[sn++] = buf[bi];
if (bi < bn)
break;
bn = fread(buf,
1, SIZE, stdin);
bi =
0;
}
s[sn] =
0;
return sn;
}
bool read(
int& x) {
int n = read(str), bf;
if (!n)
return 0;
int i =
0;
if (str[i] ==
'-') bf = -
1, i++;
else bf =
1;
for (x =
0; i < n; i++) x = x *
10 + str[i] -
'0';
if (bf <
0) x = -x;
return 1;
}
};
#define read(x) FastIO::read(x)
using namespace std;
const int maxn =
1007;
int n, m, mp[maxn][maxn], link[maxn];
bool vis[maxn];
bool dfs(
int u,
int minn) {
fep(i,m) {
int v = i+n;
if(vis[v] || mp[u][v] < minn)
continue;
vis[v] =
true;
if(link[v] == -
1 || dfs(link[v], minn)) {
link[u] = v;
link[v] = u;
return true;
}
}
return false;
}
bool match(
int minn) {
clr(link, -
1);
int ans =
0;
fep(i,n)
if(link[i] == -
1) {
clr(vis,
0);
if(dfs(i, minn)) ans++;
}
return ans == n;
}
int main() {
#ifndef ONLINE_JUDGE
freopen(
"../in.txt",
"r", stdin);
#endif
while(read(n)&&read(m)) {
fep(i,n) fep(j,m) read(mp[i][n+j]), mp[n+j][i] = mp[i][n+j];
int l=
0, r=
1000, mid, ans;
while(l<=r) {
mid = l+r>>
1;
if(match(mid)) {
ans = mid;
l = mid+
1;
}
else r = mid-
1;
}
printf(
"%d\n", ans);
}
return 0;
}