题目链接:http://poj.org/problem?id=2536
题意:有若干只田鼠,给出他们的坐标,有若干个洞,同样给出坐标,当遇到危险时田鼠可以在s秒内跑进一个洞,但一个洞只能容纳一只地鼠,给出田鼠的速度v,问遇到危险最多有多少只田鼠可以进洞
思路:如果田鼠i与地洞j的距离少于s*v,则代表它可以进入该洞,G[i][j]=1,建立二分图,用匈牙利算法求最大匹配
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
//#include <cmath>
#define maxn 130
#define eps 0.00000001
using namespace std;
double x1[maxn],y1[maxn],x2[maxn],y2[maxn];
int G[maxn][maxn],list[maxn],vis[maxn];
int n,m,s,vv;
int check(int u,int v)
{
double dis=(x1[u]-x2[v])*(x1[u]-x2[v])+(y1[u]-y2[v])*(y1[u]-y2[v]);
// cout<<dis<<"::::"<<s*s<<endl;
if (dis<=s*s*vv*vv) return 1;
else return 0;
}
int find(int u)
{
for (int i=0;i<m;i++)
{
if (G[u][i]==1 && vis[i]==0)
{
vis[i]=1;
if (list[i]==-1 || find(list[i]))
{
list[i]=u;
return 1;
}
}
}
return 0;
}
int hungry()
{
int sum=0;
for (int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if (find(i)) sum++;
}
return sum;
}
int main()
{
while (scanf("%d%d%d%d",&n,&m,&s,&vv)!=EOF)
{
memset(G,0,sizeof(G));
memset(list,-1,sizeof(list));
for (int i=0;i<n;i++)
{
scanf("%lf%lf",&x1[i],&y1[i]);
}
for (int j=0;j<m;j++)
{
scanf("%lf%lf",&x2[j],&y2[j]);
}
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (check(i,j))
{
G[i][j]=1;//cout<<i<<":"<<j<<endl;
}
}
}
int res=n-hungry();
printf("%d\n",res);
}
}