Bullet
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
In GGO, a world dominated by gun and steel, players are fighting for the honor of being the strongest gunmen. Player Shino is a sniper, and her aimed shot kills one monster at a time. Now she is in an n \times nn×n map, and there are monsters in some grids. Each monster has an experience. As a master, however, Shino has a strange self-restrain. She would kill at most one monster in a column, and also at most one in a row. Now she wants to know how to get max experience, under the premise of killing as many monsters as possible.
Input
The first line contains an integer nn. (n<=500)
Then n lines follow. In each line there are n integers, and AijAij represents the experience of the monster at grid (i,j)(i,j). If Aij=0Aij=0, there is no monster at grid (i,j)(i,j).
The experience is the minimal experience of all the monster which are killed.
It guaranteed that the maximum of the experience of the monster is not larger than 10^9
Output
One integer, the value of max experience.
Sample Input
2 2 0 1 8
Sample Output
2
簡單的匹配,二分答案。
//#include<bits/stdc++.h>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define sdddd(x,y,z,k) scanf("%d%d%d%d", &x, &y, &z, &k)
#define sddd(x,y,z) scanf("%d%d%d", &x, &y, &z)
#define sdd(x,y) scanf("%d%d", &x, &y)
#define sd(x) scanf("%d", &x)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
//#define mp make_pair
#define pb push_back
#define ms(x, y) memset(x, y, sizeof x)
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1105;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
int n;
int mp[maxn][maxn];
int used[maxn], mat[maxn];
int fd, ans;
bool Find(int x){
rep(i, 1, n){
if(mp[x][i] != 0 && mp[x][i] >= fd && !used[i]){
used[i] = true;
if(!mat[i] || Find(mat[i])){
mat[i] = x;
return true;
}
}
}
return false;
}
int Match(){
ms(mat, 0);
int cnt = 0;
rep(i, 1, n){
ms(used, 0);
if(Find(i))
cnt++;
}
return cnt;
}
int main()
{
std::ios::sync_with_stdio(false);
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
cin >> n;
int l = INF, r = -INF;
rep(i, 1, n){
rep(j, 1, n){
cin >> mp[i][j];
l = min(mp[i][j], l);
r = max(mp[i][j], r);
}
}
fd = 0;
int cnt = Match();
while(l <= r){
int mid = (l+r)/2;
fd = mid;
if(Match() == cnt){
ans = mid;
l = mid+1;
}
else{
r = mid-1;
}
}
cout <<ans <<endl;
return 0;
}