题目大意:有n只老鼠,m个洞,一个洞只能藏一只老鼠。
有一群鹰来了,老鼠们要赶紧躲到洞里才不会被抓走。
现在给出每只老鼠的坐标,每个洞的坐标,老鼠的速度,和鹰捉到老鼠的时间,问鹰最少能抓到几只老鼠
解题思路:求出每只老鼠和每个洞之间的距离,然后除于老鼠的速度,看在鹰捉到老鼠的时间内能否跑到该洞中。
然后将老鼠和洞分成两个点集,进行二分图的最大匹配,然后n-最大匹配就是鹰至少能抓到的老鼠的数量了
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 110;
const double esp = 1e-7;
double dis[N][N], pos[N][2], hole[N][2];
int g[N][N], vis[N], link[N], n, m, s, v;
double distance(double x1, double x2, double y1, double y2) {
return sqrt((x1- x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
void init() {
for(int i = 0; i < n; i++)
scanf("%lf%lf", &pos[i][0], &pos[i][1]);
for(int i = 0; i < m; i++)
scanf("%lf%lf", &hole[i][0], &hole[i][1]);
memset(g, 0, sizeof(g));
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
dis[i][j] = distance(pos[i][0], hole[j][0], pos[i][1], hole[j][1]);
if(dis[i][j] / v - s <= esp)
g[i][j] = 1;
}
memset(link, -1, sizeof(link));
}
bool dfs(int u) {
for(int i = 0; i < m; i++) {
if(vis[i] || !g[u][i])
continue;
vis[i] = 1;
if(link[i] == -1 || dfs(link[i])) {
link[i] = u;
return true;
}
}
return false;
}
void hungary() {
int ans = 0;
for(int i = 0; i < n; i++) {
memset(vis, 0, sizeof(vis));
if(dfs(i))
ans++;
}
printf("%d\n", n - ans);
}
int main() {
while(scanf("%d%d%d%d", &n, &m, &s, &v) != EOF) {
init();
hungary();
}
return 0;
}
时间: 2024-11-06 11:15:19