Description
小杉家族r个人正在一片空地上散步,突然,外星人来了……留给小杉家族脱逃的时间只有t秒,每个小杉都有一个跑的速度v。总共有a个传送点,小杉们必须在t秒内到达传送点才能脱逃,另外一个小杉进入一个传送点以后,该传送点就会消失。
现在请你安排一种方案,使脱逃的小杉尽可能的多。
Input
每组测试数据的第一行有三个整数r和a和t(0<a,r,t≤1000)
第二行有a对实数,第i对数表示第i个传送点的坐标,这些坐标绝对值均不超过1e6。
接下来r行,每行有三个实数x,y,v,表示第i个小杉的坐标和奔跑的速度。
Output
对每组测试数据输出一行,仅有一个整数s,表示最多有多少个小杉能成功脱逃。
Sample Input
1 1 1
1 1
1 1 1
Sample Output
1
Hint
100%的数据:0<a,r,t≤1000。
思路
把所有这个小衫能够到达的传送点和该小衫建边,造一个二分图,在图上找最大匹配
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000005;
const int M=1005;
int ans,n,m,t,vis[M],adj[N],nxt[N],head[M],match[M],tot;
double xx,yy,v,x[M],y[M];
void add(int u,int v)
{
tot++;
nxt[tot]=head[u];
head[u]=tot;
adj[tot]=v;
}
bool find(int u)
{
int i;
for(i=head[u];i;i=nxt[i])
{
int v=adj[i];
if(!vis[v])
{
vis[v]=1;
if(match[v]==0||find(match[v]))
{
match[v]=u;
return 1;
}
}
}
return 0;
}
int main()
{
int k,i;
scanf("%d%d%d",&n,&m,&t);
for(k=1;k<=m;k++)
cin>>x[k]>>y[k];
for(k=1;k<=n;k++)
{
cin>>xx>>yy>>v;
for(i=1;i<=m;i++)
if(sqrt((xx-x[i])*(xx-x[i])+(yy-y[i])*(yy-y[i]))<=t*v)
add(k,i);
}
for(int k=1;k<=n;k++)
{
memset(vis,0,sizeof(vis));
ans+=find(k);
}
printf("%d\n",ans);
return 0;
}
这个死double调了蒟蒻一个半小时