题目给定N个老鼠,M个洞,在规定的时间后,将有天敌来猎捉它们,每个老鼠都有一个速度,求一种躲藏的策略,使得受威胁的老鼠最少。(每个洞中只能藏一只老鼠)
该题可以将老鼠到达可及洞的情况看作是一个匹配,于是该题就是求一个老鼠到洞的最大匹配。
代码如下:
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAXN 100
using namespace std;
int n, m, s, v;
int G[MAXN+5][MAXN+5], visit[MAXN+5], marry[MAXN+5];
struct info
{
double x, y, dist;
}d[MAXN+5];
double dist(double x1, double y1, double x2, double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int path(int u)
{
for (int i = 1; i <= m; ++i) {
if (!G[u][i] || visit[i]) {
continue;
}
visit[i] = 1;
if (!marry[i] || path(marry[i])) {
marry[i] = u;
return 1;
}
}
return 0;
}
int main()
{
double xx, yy;
int ans;
while (scanf("%d %d %d %d", &n, &m, &s, &v) == 4) {
ans = 0;
memset(G, 0, sizeof (G));
memset(marry, 0, sizeof (marry));
for (int i = 1; i <= n; ++i) {
scanf("%lf %lf", &d[i].x, &d[i].y);
}
for (int i = 1; i <= m; ++i) {
scanf("%lf %lf", &xx, &yy);
for (int j = 1; j <= n; ++j) {
if (s*v >= dist(d[j].x, d[j].y, xx, yy))
G[j][i] = 1; // j点到i洞可达
}
}
for (int i = 1; i <= n; ++i) {
memset(visit, 0, sizeof (visit));
if (path(i)) {
++ans;
}
}
printf("%d\n", n-ans);
}
return 0;
}