【题目描述】
草原某片区域上有 N 个地鼠正在地面寻食,附近有 M 个地鼠洞,地鼠和地鼠洞的当前位置用坐标(x,y)表示。每个洞只能容纳一个地鼠。
输入包含多组数据。
每组数据的第一行包含四个不超过100的正整数:N,M,S,V。
接下来的n行,每行两个实数,表示一个地鼠的坐标;
接下来M行,每行两个实数,表示一个地鼠洞的坐标。
所有的距离单位是“米”,所有的时间单位是“秒”,所有的速度单位是“米/秒”。
【输出格式】
对每组数据输出一行,一个整数,表示至少要被老鹰吃掉的地鼠的数量。
【输入样例】
2 2 5 10
1.0 1.0
2.0 2.0
100.0 100.0
20.0 20.0
【输出样例】
草原某片区域上有 N 个地鼠正在地面寻食,附近有 M 个地鼠洞,地鼠和地鼠洞的当前位置用坐标(x,y)表示。每个洞只能容纳一个地鼠。
一只老鹰正飞向这里,如果地鼠在 S 秒内没有进入地鼠洞,则会被老鹰吃掉。所有地鼠都以同一速度 V 进行逃生。请你帮地鼠家族设计一个优秀的逃生策略,使得损失的地鼠最少。
【输入格式】
每组数据的第一行包含四个不超过100的正整数:N,M,S,V。
接下来的n行,每行两个实数,表示一个地鼠的坐标;
接下来M行,每行两个实数,表示一个地鼠洞的坐标。
所有的距离单位是“米”,所有的时间单位是“秒”,所有的速度单位是“米/秒”。
【输出格式】
对每组数据输出一行,一个整数,表示至少要被老鹰吃掉的地鼠的数量。
【输入样例】
2 2 5 10
1.0 1.0
2.0 2.0
100.0 100.0
20.0 20.0
【输出样例】
1
这就是二分图最大匹配的板题,只用找出每只地鼠能到达的所有洞的距离,再将洞与地鼠进行最大匹配,最后输出总数-匹配数就是答案。
贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 105
int n,m,s,v;
int match[N]; //表示i点是否已经匹配
int map[N][N]; //表示i号地鼠能否到达j号洞
bool visit[N]; //表示在一次匹配中是否被访问过
struct node{ //a记录地鼠坐标,b记录洞的坐标
double x,y;
};
node a[N],b[N];
double dis(double x1,double y1,double x2,double y2) //计算地鼠与洞之间的距离
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool dfs(int v) //搜索洞v和地鼠i
{
int tmp;
for(int i=1;i<=n;i++)
if(map[i][v]&&!visit[i]) //寻找v的对应点且该点没有尝试过更改匹配
{
visit[i]=true; //设置访问标记
tmp=match[i]; //保存i原匹配点
match[i]=v; //压入新匹配点
if(tmp==0||dfs(tmp)) //如果是初始值则增广成功返回
return true;
match[i]=tmp; //如果失败就重新找点增广,恢复i点原匹配
}
return false; //i点无法增广
}
int main()
{
while(scanf("%d%d%d%d",&n,&m,&s,&v)!=EOF) //因为是多组数据所以用while读入
{
memset(match,0,sizeof(match));
memset(map,0,sizeof(map));
for(int i=1;i<=n;i++) //地鼠坐标
scanf("%lf%lf",&a[i].x,&a[i].y);
for(int i=1;i<=m;i++) //洞的坐标
scanf("%lf%lf",&b[i].x,&b[i].y);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(dis(a[i].x,a[i].y,b[j].x,b[j].y)<=v*s) //如果能进洞就在map上表示为真
map[i][j]=1;
}
int ans=0;
for(int j=1;j<=m;j++)
{
memset(visit,0,sizeof(visit));
if(dfs(j)) //匈牙利算法计算最大匹配,每匹配一个地鼠就将答案加一
ans++;
}
cout<<n-ans<<endl; //总数减去能活下来的地鼠即为答案
}
return 0;
}