POJ 2536 Gopher II(二分图最大匹配)
http://poj.org/problem?id=2536
题意:
有n个地鼠和m个洞,有鹰飞来时,n个地鼠如果能在s秒从当前位置回到一个洞,就能不死,一个洞能容纳一个地鼠,它们的速度为v。求可能死的地鼠个数的最小值。
分析:
如果一个地鼠能在s秒内到达一个特定的洞,那么就在它们之间两一条无向边. 我们所建立的图是一个二分图,左边是地鼠,右边是洞.
现在我们要求的就是该图的最大匹配数.
那么可能死的地鼠个数 = n – 最大匹配数.
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring >
#include<vector>
#include<cmath>
using namespace std;
const int maxn=300+10;
struct Max_Match
{
int n,m;
vector<int>g[maxn];
bool vis[maxn];
int left[maxn];
void init(int n,int m )
{
this->n=n;
this->m=m;
for(int i=1;i<=n;i++)
g[i].clear();
memset(left,-1,sizeof left);
}
bool match(int u)
{
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(!vis[v])
{
vis[v]=true;
if(left[v]==-1||match(left[v]))
{
left[v]=u;
return true;
}
}
}
return false;
}
int solve()
{
int ans=0;
for(int i=1;i<=n;i++)
{
memset(vis,false,sizeof vis);
if(match(i))
ans++;
}
return ans;
}
}MM;
struct node
{
double x,y;
}mou[maxn],hole[maxn];
int main()
{
int n,m,s,v;
while(~scanf("%d%d%d%d",&n,&m,&s,&v))
{
for(int i=1;i<=n;i++)
scanf("%lf%lf",&mou[i].x,&mou[i].y);
for(int i=1;i<=m;i++)
scanf("%lf%lf",&hole[i].x,&hole[i].y);
MM.init(n,m);
double sum;
double len=(double)s*v;
len=len*len;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
sum=(mou[i].x-hole[j].x)*(mou[i].x-hole[j].x)+(mou[i].y-hole[j].y)*(mou[i].y-hole[j].y);
//cout<<sum<<endl;
if(sum<=len)
MM.g[i].push_back(j);
}
printf("%d\n",n-MM.solve());
}
return 0;
}