POJ 2536 Gopher II (ZOJ 2536) 二分图匹配

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1882

http://poj.org/problem?id=2536

题目大意:

有n之地鼠和m个地洞,他们需要在s秒内以v秒的速度跑进洞中,否则会被鹰抓走。给定每个地鼠和洞的坐标,每个洞最多容纳一只地鼠,问最小有危险的地鼠个数。

思路:

跑回学校了~来A几题。 几个月前看的题不会做T T,现在好简单。。。

本题可以转化为二分图匹配。如果地鼠到洞的时间小于s,那么久建一条边,求出最大匹配,然后用总数减去最大匹配即可。



#include<cstdio>
#include<cmath>
#include<cstring>
const int MAXN=200+10;
int head[MAXN],len,res[MAXN];
bool vis[MAXN];
struct edge
{
	int to,next;
}e[MAXN*MAXN];

void add(int from,int to)
{
	e[len].to=to;
	e[len].next=head[from];
	head[from]=len++;
}
struct point
{
	double x,y;
}gopher[MAXN],hole[MAXN];

double getlen(double x1,double y1,double x2,double y2)
{
	return sqrt( (x1-x2)*(x1-x2) +(y1-y2)*(y1-y2));
}

bool find(int a)
{
	for(int i=head[a];i!=-1;i=e[i].next)
	{
		int id=e[i].to;
		if(!vis[id])
		{
			vis[id]=true;
			if(res[id]==0 || find(res[id]) )
			{
				res[id]=a;
				return true;
			}
		}
	}
	return false;
}


int main()
{
	int n,m;
	double s,v;
	while(~scanf("%d%d%lf%lf",&n,&m,&s,&v))
	{
		memset(head,-1,sizeof(head));
		memset(res,0,sizeof(res));
		len=0;

			for(int i=1;i<=n;i++)
				scanf("%lf%lf",&gopher[i].x,&gopher[i].y);

			for(int i=1;i<=m;i++)
				scanf("%lf%lf",&hole[i].x,&hole[i].y);

			for(int i=1;i<=n;i++)
			{
				for(int j=1;j<=m;j++)
				{
					double len=getlen(gopher[i].x,gopher[i].y,hole[j].x,hole[j].y);
					if( len/v < s)
						add(i,j);				
				}
			}
			int ans=0;
			for(int i=1;i<=n;i++)
			{
				memset(vis,0,sizeof(vis));
				if(find(i)) ans++;
			}
			printf("%d\n",n-ans);
	}

	return 0;
}


你可能感兴趣的:(编程,ACM,poj,二部图)