前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU 2389 Rain on your Parade(二分图最大匹配--Hopcroft-Karp算法)

HDU 2389 Rain on your Parade(二分图最大匹配--Hopcroft-Karp算法)

作者头像
Ch_Zaqdt
发布2019-01-10 16:11:44
7172
发布2019-01-10 16:11:44
举报
文章被收录于专栏:Zaqdt_ACM

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2389

       题意是天马上就要下雨了,然后有n个人,m把伞,然后分别给出人的坐标和他们跑的速度,以及伞的坐标,然后问在t时间内,最多能有多少人拿到伞。

       题目读懂的话,就很容易就看出这是一道二分图的最大匹配问题,但是这道题数据范围'挺大'的都是3000,所以用匈牙利算法会超时,然后就敲了一遍Hopcroft-Carp的板子。图论问题主要还是看怎么去存图,这道题的话我们先把每个人的坐标和速度存起来,然后在输入伞的坐标的时候遍历一下,计算一下每个人能不能在t时间内拿到这把伞,如果可以就把这两个点连边存起来,然后跑一遍HK就好了。


AC代码:

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年11月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档