POJ 2536 地鼠

【题目描述】
    草原某片区域上有 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;
}   

猜你喜欢

转载自blog.csdn.net/g21glf/article/details/80940817