题目链接:POJ 2536 Gopher II
如果某个老鼠能在s秒内跑进某个洞,这两者之间连一条边,这样图就建好了,注意最后问的是挂掉的老鼠,所以应该是n - MAxMatch()。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAX_N = 200 + 20;
bool _map[MAX_N][MAX_N], vis[MAX_N];
int link[MAX_N];
struct Point
{
double x, y;
};
Point p[MAX_N];
int n, m, s, v;
bool dfs(int u)
{
for(int i = n + 1; i <= n + m; i++)
{
if(!vis[i] && _map[u][i])
{
vis[i] = true;
if(link[i] == -1 || dfs(link[i]))
{
link[i] = u;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int num = 0;
memset(link, -1, sizeof(link));
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
if(dfs(i))
num++;
}
return num;
}
double dis(int a, int b)
{
return sqrt((p[a].x - p[b].x) * (p[a].x - p[b].x) + (p[a].y - p[b].y) * (p[a].y - p[b].y));
}
bool isOK(int a, int b)
{
if(dis(a, b) / v > s)
return false;
return true;
}
int main()
{
while(scanf("%d%d%d%d", &n, &m, &s, &v) != EOF)
{
memset(_map, 0, sizeof(_map));
for(int i = 1; i <= n + m; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
for(int i = 1; i <= n; i++)
for(int j = n + 1; j <= n + m; j++)
if(isOK(i, j))
_map[i][j] = 1;
printf("%d\n", n - MaxMatch());
}
return 0;
}