题意:有n个gophers和m个gophers的洞,hawk会抓他们,一个洞只能进一只gopher,现在给出gophers的坐标和洞的坐标,以及hawk的飞行时间和速度,求能被抓的gopher个数。
解法:二分图最大匹配,建图是这样的,gopher跟洞之间的距离如果小于hawk的路程,则说明这个gopher可以到达这个洞,于是连一条边。然后匈牙利就可以了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
struct p
{
double x,y;
}a[310],b[310];
bool g[310][310];
bool flag,visit[310];
int match[310];
int p,n;
double dis(double x1,double y1,double x2,double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
bool dfs(int u)
{
for (int i = 1; i <= n; ++i)
{
if (g[u][i] && !visit[i])
{
visit[i] = true;
if (match[i] == -1 || dfs(match[i]))
{
match[i] = u;
return true;
}
}
}
return false;
}
int main()
{
while(~scanf("%d%d",&p,&n))
{
int s;
double v;
scanf("%d%lf",&s,&v);
memset(g,false,sizeof(g));
memset(match,-1,sizeof(match));
for(int i = 1; i <= p; i++) scanf("%lf%lf",&a[i].x,&a[i].y);
for(int i = 1; i <= n; i++) scanf("%lf%lf",&b[i].x,&b[i].y);
for(int i = 1; i <= p; i++)
{
for(int j = 1; j <= n; j++)
{
if(dis(a[i].x,a[i].y,b[j].x,b[j].y) <= s*v)
{
g[i][j] = true;
//printf("%d%d\n",i,j);
}
}
}
int ans = 0;
for(int i = 1; i <= p; i++)
{
memset(visit,false,sizeof(visit));
if(dfs(i))
ans ++;
}
printf("%d\n",p - ans);
}
return 0;
}