题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2389
题意是天马上就要下雨了,然后有n个人,m把伞,然后分别给出人的坐标和他们跑的速度,以及伞的坐标,然后问在t时间内,最多能有多少人拿到伞。
题目读懂的话,就很容易就看出这是一道二分图的最大匹配问题,但是这道题数据范围'挺大'的都是3000,所以用匈牙利算法会超时,然后就敲了一遍Hopcroft-Carp的板子。图论问题主要还是看怎么去存图,这道题的话我们先把每个人的坐标和速度存起来,然后在输入伞的坐标的时候遍历一下,计算一下每个人能不能在t时间内拿到这把伞,如果可以就把这两个点连边存起来,然后跑一遍HK就好了。
AC代码:
#include <bits/stdc++.h>
#define maxn 3010
#define inf 0x3f3f3f3f
using namespace std;
struct Node{
int to,next;
}Edge[maxn*maxn];
struct node{
double x,y,v;
}a[maxn];
int head[maxn],num;
int lx[maxn],ly[maxn],dx[maxn],dy[maxn];
bool vis[maxn];
int T,n,m,t,dis;
void init(){
memset(lx,-1,sizeof(lx));
memset(ly,-1,sizeof(ly));
memset(head,-1,sizeof(head));
num = 0;
}
void add(int u,int v){
Edge[num].to = v;
Edge[num].next = head[u];
head[u] = num ++;
}
double dist(double x, double y, double xx, double yy){
return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
}
bool Search(){
queue<int> q;
dis = inf;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=0;i<n;i++){
if(lx[i] == -1){
q.push(i);
dx[i] = 0;
}
}
while(!q.empty()){
int u = q.front();
q.pop();
if(dx[u] > dis) break;
for(int i=head[u];i!=-1;i=Edge[i].next){
int v = Edge[i].to;
if(dy[v] == -1){
dy[v] = dx[u] + 1;
if(ly[v] == -1) dis = dy[v];
else{
dx[ly[v]] = dy[v] + 1;
q.push(ly[v]);
}
}
}
}
return dis != inf;
}
bool dfs(int u){
for(int i=head[u];i!=-1;i=Edge[i].next){
int v = Edge[i].to;
if(!vis[v] && dy[v] == dx[u] + 1){
vis[v] = true;
if(ly[v] != -1 && dy[v] == dis) continue;
if(ly[v] == -1 || dfs(ly[v])){
ly[v] = u;
lx[u] = v;
return true;
}
}
}
return false;
}
int Hopcroft_Karp(){
int sum = 0;
while( Search() ){
memset(vis,false,sizeof(vis));
for(int i=0;i<n;i++){
if(lx[i] == -1 && dfs(i)) sum ++;
}
}
return sum;
}
int main()
{
int Case = 1;
scanf("%d",&T);
while(T--){
init();
scanf("%d%d",&t,&n);
for(int i=0;i<n;i++){
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].v);
}
scanf("%d",&m);
for(int i=0;i<m;i++){
double xx, yy;
scanf("%lf%lf",&xx,&yy);
for(int j=0;j<n;j++){
double zz = dist(xx, yy, a[j].x, a[j].y);
if(a[j].v * t >= zz){
add(j ,i);
}
}
}
int ans = Hopcroft_Karp();
printf("Scenario #%d:\n%d\n\n",Case ++, ans);
}
return 0;
}