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/Others)

Total Submission(s): 3033    Accepted Submission(s): 952

Problem 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 <= si <= 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

Source

HDU 2008-10 Public Contest

题意:第一行案例数,每个案例第一行 代表还有多少单位时间开始下雨,然后是 N个访客,接下来N行是 每个访客的位置(一维坐标平面内)和他的移动速度,接下来M行 代表雨伞数目,接下来M行表示各个雨伞的位置,问在下雨前 最多有多少人能够拿到雨伞(两个人不能共用一把伞)。

解析:以在给定的时间内 人能到达伞的位置 建边,二分最大匹配,如果直接用经典匈牙利算法一定分超时的,可用Hopcroft-Karp算法(O(sqrt(n)*edgnum)). 546MS
AC。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<math.h>
using namespace std;
const int N = 3005;
const int INF=1<<28;

int head[N],to[N*N],next1[N*N],tot;  //存图
int dx[N],dy[N],dis;                 //左边部分距离,右边部分距离,记录右边部分没有被匹配过的点的最大距离
int machx[N],nx,machy[N];            //左边部分点匹配右边点,左边部分的点个数,右边部分点匹配左边的点
bool vist[N];

void addEdg(int u,int v){
    to[tot]=v; next1[tot]=head[u]; head[u]=tot++;
}
bool searchpath(){//找有没有增广路
    queue<int>q;
    dis=INF;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));

    for(int i=1; i<=nx; i++)
        if(machx[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=next1[i]){
            int v=to[i];
            if(dy[v]==-1){
                dy[v]=dx[u]+1;
                if(machy[v]==-1)
                    dis=dy[v];
                else{
                    dx[machy[v]]=dy[v]+1;
                    q.push(machy[v]);
                }
            }
        }
    }
    return dis!=INF;
}
bool findroad(int u){
    for(int i=head[u]; i!=-1; i=next1[i]){
        int v=to[i];
        if(!vist[v]&&dy[v]==dx[u]+1){
            vist[v]=1;
            if(machy[v]!=-1&&dy[v]==dis)
                continue;
            if(machy[v]==-1||findroad(machy[v])){
                machy[v]=u; machx[u]=v;  return true;
            }
        }
    }
    return false;
}
int MaxMatch(){
    int ans=0;
    memset(machx,-1,sizeof(machx));
    memset(machy,-1,sizeof(machy));
    while( searchpath() ){
        memset(vist,0,sizeof(vist));
        for(int i=1; i<=nx; i++)
            if(machx[i]==-1)
            ans+=findroad(i);
    }
    return ans;
}
//-------------上面部分的代码为模板---------------------

struct node{
    int x,y;
    double dis;
}man[N],umb[N];

double countDis(int u,int v){
    return sqrt((man[u].x-umb[v].x)*(man[u].x-umb[v].x)*1.0+(man[u].y-umb[v].y)*(man[u].y-umb[v].y)*1.0);
}
int main(){
    int T,ny,tim,c=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&tim,&nx);
        for(int i=1;i<=nx;i++){
            scanf("%d%d%lf",&man[i].x,&man[i].y,&man[i].dis);
            man[i].dis*=tim;
        }
        scanf("%d",&ny);
        for(int i=1;i<=ny;i++)
            scanf("%d%d",&umb[i].x,&umb[i].y);

//---------------------建图---------------------
        tot=0;
        memset(head,-1,sizeof(head));
        for(int u=1;u<=nx;u++)
            for(int v=1;v<=ny;v++)
            if(man[u].dis>=countDis(u,v))
                addEdg(u,v);
//----------------------------------------------
        int ans=MaxMatch();
        printf("Scenario #%d:\n%d\n\n",++c,ans);
    }
    return 0;
}
时间: 2024-08-05 11:18:51

HDU 2389 Rain on your Parade (二分图匹配(Hopcroft-Carp的算法模板))的相关文章

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

题目链接: Hdu 3289 Rain on your Parade 题目描述: 有n个客人,m把雨伞,在t秒之后将会下雨,给出每个客人的坐标和每秒行走的距离,以及雨伞的位置,问t秒后最多有几个客人可以拿到雨伞? 解题思路: 数据范围太大,匈牙利算法O(n*m)果断华丽丽的TLE,请教了一下度娘,发现还有一种神算法—— Hopcroft-Karp,然后就get√新技能,一路小跑过了,有一点不明白的是hdu上竟然有人0ms过,这又是什么神姿势(吓哭!!!!!),额.........,扯远了.  H

hdu 2389 Rain on your Parade(二分图HK算法)

#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; const int inf=0x3f3f3f3f; const int maxn=3003; const int maxm=maxn*maxn; int xlink[maxn],ylink[maxn]; int dx[maxn

HDU 2389 Rain on your Parade

http://acm.hdu.edu.cn/showproblem.php?pid=2389 题意:给暴风雨到来的时刻,m个人的坐标和单位速度,和n个救生衣的坐标.每个救生衣只能匹配一个人,求最多有多少人可以得到救生衣. 题解:典型二分图最大匹配题型.因为点比较多,使用Hopcroft-Karp算法.讲解:http://blog.csdn.net/wall_f/article/details/8248373 http://www.cnblogs.com/-sunshine/archive/201

HDU 2389 ——Rain on your Parade——————【Hopcroft-Karp求最大匹配、sqrt(n)*e复杂度】

Rain on your Parade Time Limit:3000MS     Memory Limit:165535KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2389 Description You’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is h

hdu 2063 过山车(二分图匹配最大匹配数模板)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10776    Accepted Submission(s): 4748 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par

hdu-2389.rain on your parade(二分匹配HK算法)

Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Others)Total Submission(s): 6752    Accepted Submission(s): 2117 Problem Description You’re giving a party in the garden of your villa by the sea. The p

HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 49    Accepted Submission(s): 14 Problem Description There is a kindom of obsession, so people in this kingdom do things very

【HDOJ】2389 Rain on your Parade

读题显然是二分图匹配,看成guest与umbrella的匹配.匈牙利果断TLE了,其实时间卡的相当紧.HK过的,750ms. 1 /* 2389 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #

【HDU 1150】Machine Schedule(二分图匹配)

机器的不同模式为点,对于每个job,建两条边 A机器需要的模式<->B机器需要的模式. 问题转化为最小点覆盖,然后用二分图的最小点覆盖==最大匹配,用匈牙利算法解. #include <cstdio> #include <cstring> const int N=105<<1; const int M=1001<<1; struct edge{ int to,next; }e[M]; int head[N],tot; void add(int u