题目:
http://poj.org/problem?id=2536
题意:
给出n只虫,m个洞的坐标,虫只有到达洞中才安全,一个洞最多装一只虫,超过s秒没有在洞中的虫子就会被吃掉。虫子的行走速度是v,求出被吃掉的虫子最少数量。
思路:
二分图匹配。
左集表示虫子,右集表示洞,虫子与洞的距离小于等于s*v 时连边,求得的最大匹配数为受到保护的虫子,则答案为n-最大匹配数。
AC.
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 105;
struct node {
double x, y;
}gop[maxn], hole[maxn];
int g[maxn][maxn];
int linker[maxn];
bool used[maxn];
int uN, vN;
double dis(int gi, int hi)
{
return (gop[gi].x - hole[hi].x) * (gop[gi].x - hole[hi].x) +
(gop[gi].y - hole[hi].y) * (gop[gi].y - hole[hi].y);
}
bool dfs(int u)
{
for(int v = 0; v < vN; ++v) {
if(g[u][v] && !used[v]) {
used[v] = true;
if(linker[v] == -1 || dfs(linker[v])) {
linker[v] = u;
return true;
}
}
}
return false;
}
int hungary()
{
int res = 0;
memset(linker, -1, sizeof(linker));
for(int u = 0; u < uN; ++u) {
memset(used, 0, sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main()
{
//freopen("in", "r", stdin);
int n, m, s, v;
while(~scanf("%d %d %d %d", &n, &m, &s, &v)) {
for(int i = 0; i < n; ++i) {
scanf("%lf %lf", &gop[i].x, &gop[i].y);
}
for(int i = 0; i < m; ++i) {
scanf("%lf %lf", &hole[i].x, &hole[i].y);
}
double len = (double)s*v*s*v;
memset(g, 0, sizeof(g));
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
double d = dis(i, j);
//printf("%lf\n", d);
if(d <= len) g[i][j] = 1;
}
}
uN = n;
vN = m;
int ans = hungary();
printf("%d\n", n - ans);
}
return 0;
}