Rain on your Parade

Time Limit:3000MS     Memory Limit:165535KB     64bit IO Format:%I64d & %I64u

Description

You’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It’s a warm, sunny evening, and a soothing wind sends fresh, salty air from the sea. The evening is progressing just as you had imagined. It could be the perfect end of a beautiful day. 
But nothing ever is perfect. One of your guests works in weather forecasting. He suddenly yells, “I know that breeze! It means its going to rain heavily in just a few minutes!” Your guests all wear their best dresses and really would not like to get wet, hence they stand terrified when hearing the bad news. 
You have prepared a few umbrellas which can protect a few of your guests. The umbrellas are small, and since your guests are all slightly snobbish, no guest will share an umbrella with other guests. The umbrellas are spread across your (gigantic) garden, just like your guests. To complicate matters even more, some of your guests can’t run as fast as the others. 
Can you help your guests so that as many as possible find an umbrella before it starts to pour?

Given the positions and speeds of all your guests, the positions of the umbrellas, and the time until it starts to rain, find out how many of your guests can at most reach an umbrella. Two guests do not want to share an umbrella, however.

 

Input

The input starts with a line containing a single integer, the number of test cases. 
Each test case starts with a line containing the time t in minutes until it will start to rain (1 <=t <= 5). The next line contains the number of guests m (1 <= m <= 3000), followed by m lines containing x- and y-coordinates as well as the speed si in units per minute (1 <= s i<= 3000) of the guest as integers, separated by spaces. After the guests, a single line contains n (1 <= n <= 3000), the number of umbrellas, followed by n lines containing the integer coordinates of each umbrella, separated by a space. 
The absolute value of all coordinates is less than 10000. 
 

Output

For each test case, write a line containing “Scenario #i:”, where i is the number of the test case starting at 1. Then, write a single line that contains the number of guests that can at most reach an umbrella before it starts to rain. Terminate every test case with a blank line. 
 

Sample Input

2
1
2
1 0 3
3 0 3
2
4 0
6 0
1
2
1 1 2
3 3 2
2
2 2
4 4
 

Sample Output

Scenario #1:
2
Scenario #2:
2
 
 
题目大意:T组测试数据。每组给t表示还有t分钟要下雨,然后给n,表示有n名游客,分别给出x,y,s表示二维坐标及移动速度。接着是m表示有m个避雨亭,给出x,y表示二维坐标,每个游客都不愿意跟其他人共有避雨亭,问t分钟后,最多可以有多少个游客能避雨。
 
解题思路:最大匹配。游客跟避雨亭分为二部。如果游客可以移动的距离比当前他离某个避雨亭的距离大,说明他可以过去避雨。就连一条边。对于所有游客都枚举一下。建图完成。然而这个题目不是难在建图,而是数据量大,二部图两边的顶点各有3000个。那么可能最大到9*10^6条边,如果用Hungary的v*e的复杂度,那么肯定会超时。所以这里我们用Hopcroft-Karp求最大匹配。
 
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 3100;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
struct Guest{
double x,y,s;
}guests[maxn];
struct Umbrella{
double x,y;
}umbrellas[maxn];
double distan(Guest a,Umbrella b){
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx+dy*dy);
}
vector<int>G[maxn];
int Mx[maxn], My[maxn], dx[maxn], dy[maxn], used[maxn], dis;
bool SearchP(int _n){ //传参x部的顶点个数,处理出来dx与dy数组
queue<int>Q;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
int dis = INF;
for(int i = 1; i <= _n; i++){
if(Mx[i] == -1){ //将x部的未盖点入队
dx[i] = 0;
Q.push(i);
}
}
int v;
while(!Q.empty()){
int u = Q.front(); Q.pop();
if(dx[u] > dis) break; //没有更小的dis
for(int i = 0; i < G[u].size(); i++){
v = G[u][i];
if(dy[v] == -1){ //如果y部的v没有访问过
dy[v] = dx[u] + 1; //更新dy
if(My[v] == -1){ //如果y部的v是未盖点,找到了最短增广路长度
dis = dy[v];
}else{
dx[My[v]] = dy[v] + 1; //更新v的x部匹配点
Q.push(My[v]); //将v的匹配点入队
}
}
}
}
return dis != INF; //找到了最短增广路
}
int dfs(int u){
int v;
for(int i = 0; i < G[u].size(); i++){
v = G[u][i];
if(!used[v] && dy[v] == dx[u] + 1){ //v未访问过且距离相差为1
used[v] = 1;
if(My[v] != -1 && dy[v] == dis){ //如果v不是未盖点且已经等于最短增广路距原点距离,说明有更短的可以去增广
continue;
}
if(My[v] == -1 || dfs(My[v])){ //如果v是y部未盖点或者原来跟v匹配的x部节点能另外找到一个匹配
Mx[u] = v; //匹配u、v
My[v] = u;
return true;
}
}
}
return false;
}
int MaxMatch(int ln,int rn){ //传参左、右部顶点个数,返回最大匹配个数
int ret = 0;
memset(Mx,-1,sizeof(Mx)); //x部初始化未盖点
memset(My,-1,sizeof(My)); //y部初始化未盖点
while(SearchP(ln)){
memset(used,0,sizeof(used)); //初始化未访问
for(int i = 1; i <= ln; i++){
if(Mx[i] == -1 && dfs(i)){ //如果x部为未盖点且找到了增广路
ret++;
}
}
}
return ret;
}
int main(){
int T, cas = 0, n, m;
double t;
scanf("%d",&T);
while(T--){
scanf("%lf",&t);
scanf("%d",&m);
for(int i = 0; i <= m; i++){
G[i].clear();
}
for(int i = 1; i <= m; i++){
scanf("%lf%lf%lf",&guests[i].x,&guests[i].y,&guests[i].s);
}
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%lf%lf",&umbrellas[i].x,&umbrellas[i].y);
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
double dd = distan(guests[i],umbrellas[j]);
if(guests[i].s * t >= dd){
G[i].push_back(j);
}
}
}
int res = MaxMatch(m,n);
printf("Scenario #%d:\n%d\n\n",++cas,res);
}
return 0;
}

  

 
 

HDU 2389 ——Rain on your Parade——————【Hopcroft-Karp求最大匹配、sqrt(n)*e复杂度】的更多相关文章

  1. HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade(二分图的最大匹配)

    HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade(二分图的最大匹配) Description You're giving a ...

  2. HDU 2389 Rain on your Parade(二分匹配,Hopcroft-Carp算法)

    Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Ot ...

  3. HDU 2389 Rain on your Parade

    大意:在一个二维坐标系上有nx个人和ny把伞,每个人都有自己的移动速度,问有多少人可以再 time 时间内移动到不同的雨伞处(不允许两个人共用一把伞).   输入数据: 第一行是一个T代表T组测试数据 ...

  4. HDU 2389 Rain on your Parade 最大匹配(模板题)【HK算法】

    <题目链接> 题目大意:有m个宾客,n把雨伞,预计时间t后将会下大雨,告诉你每个宾客的位置和速度,每把雨伞的位置,问你最多几个宾客能够拿到伞. 解题分析: 本题就是要我们求人与伞之间的最大 ...

  5. Hdu 3289 Rain on your Parade (二分图匹配 Hopcroft-Karp)

    题目链接: Hdu 3289 Rain on your Parade 题目描述: 有n个客人,m把雨伞,在t秒之后将会下雨,给出每个客人的坐标和每秒行走的距离,以及雨伞的位置,问t秒后最多有几个客人可 ...

  6. HDOJ 2389 Rain on your Parade

     HK.... Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K ...

  7. Hdu2389 Rain on your Parade (HK二分图最大匹配)

    Rain on your Parade Problem Description You’re giving a party in the garden of your villa by the sea ...

  8. 【HDOJ】2389 Rain on your Parade

    读题显然是二分图匹配,看成guest与umbrella的匹配.匈牙利果断TLE了,其实时间卡的相当紧.HK过的,750ms. /* 2389 */ #include <iostream> ...

  9. Rain on your Parade---hdu2389(HK求最大匹配)

    题目链接 题意:有n个客人,m把雨伞,在t秒之后将会下雨,给出每个客人的坐标和每秒行走的距离,以及雨伞的位置,问t秒后最多有几个客人可以拿到雨伞? 就是求最大匹配的  Hopcroft-Karp复杂度 ...

随机推荐

  1. Unity3D 接口使用

    C#怎么实现多继承? 说起多继承,首先大家可以想想这个问题:你知道在C#中怎么实现多继承吗? 主流的答案无非2种. 答案一:用接口啊,一个类可以继承自多个接口的.答案二:C#不支持多继承,C++才支持 ...

  2. java 文件的读写操作

    java  文件的读写操作 一.读: public String getSetting() { HttpServletRequest request=org.apache.struts2.Servle ...

  3. scala lambda 表达式 & spark RDD函数操作

    形式:(参数)=> 表达式  [ 一种匿名函数 ] 例1:map(x => x._2) 解:x=输入参数,“=>” 右边是表达式(处理参数): x._2 : x变为(**,x,**. ...

  4. B - Pie (二分)

    My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a number N ...

  5. 洛谷P3258 [JLOI2014]松鼠的新家(树上差分+树剖)

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...

  6. LB 负载均衡的层次结构(转)

    http://blog.csdn.net/mindfloating/article/details/51020767 作为后端应用的开发者,我们经常开发.调试.测试完我们的应用并发布到生产环境,用户就 ...

  7. SQL基础(一)

    经过这段时间对SQL的基础学习,下面对自己的学习做个总结或者也可以说是个回顾吧! 我练习的是在oracle数据库平台上,并且安装了PLSQL Developer工具.下面是我从小白开始一路学习的回顾: ...

  8. git 本地分支与远程分支相关操作记录

    1.远程分支中有新增分支,但自己的本地分支没有对应同步 git checkout -b [remote-branch-name] origin/[remote-branch-name] 2. 查看本地 ...

  9. springcloud系列九 整合Hystrix Dashboard

    Hystrix Dashboard是Hystrix的仪表盘组件,主要用来实时监控Hystrix的各项指标信息,通过界面反馈的信息可以快速发现系统中存在的问题. 整合快速体验: pom.xml(这个是F ...

  10. Oracle 11G R2在用EXP 导出时,空表不能导出解决办法

    11G中有个新特性,当表无数据时,不分配segment,以节省空间 解决方法: 1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segmen ...