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过,这又是什么神姿势(吓哭!!!!!),额.........,扯远了。

   Hopcroft-Karp复杂度O(sqrt(n)*m),相比匈牙利算法优化在于,Hopcroft-Karp算法每次可以扩展多条不相交增广路径。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <queue>
  4 #include <cmath>
  5 #include <cstdio>
  6 using namespace std;
  7
  8 const int maxn = 3000;
  9 const int INF = 0x3f3f3f3f;
 10 struct node
 11 {
 12     int to, next;
 13 } edge[maxn*maxn+10];
 14 struct point
 15 {
 16     double x, y, num;
 17 };
 18 point p_gue[maxn+5], p_umb[maxn+5];
 19 int head[maxn+5], vis[maxn+5], n, m, tot, dis;
 20 int cx[maxn+5], cy[maxn+5], dx[maxn+5], dy[maxn+5];
 21
 22 void Add (int from, int to)
 23 {
 24     edge[tot].to = to;
 25     edge[tot].next = head[from];
 26     head[from] = tot ++;
 27 }
 28
 29 bool bfs ()
 30 {//寻找多条无公共点的最短增广路
 31     queue <int> Q;
 32     dis = INF;
 33     memset (dx, -1, sizeof(dx));
 34     //左边顶点i所在层编号
 35     memset (dy, -1, sizeof(dy));
 36     //右边顶点i所在层编号
 37     for (int i=1; i<=n; i++)
 38         if (cx[i] == -1)
 39         {
 40             Q.push(i);
 41             dx[i] = 0;
 42         }
 43     while (!Q.empty())
 44     {
 45         int u = Q.front();
 46         Q.pop();
 47         if (dx[u] > dis)
 48             break;
 49         for (int i=head[u]; i!=-1; i=edge[i].next)
 50         {
 51             int v = edge[i].to;
 52             if (dy[v] == -1)
 53             {
 54                 dy[v] = dx[u] + 1;
 55                 if (cy[v] == -1)
 56                     dis = dy[v];
 57                 else
 58                 {
 59                     dx[cy[v]] = dy[v] + 1;
 60                     Q.push(cy[v]);
 61                 }
 62             }
 63         }
 64     }
 65     return dis != INF;
 66 }
 67 int dfs (int u)
 68 {//寻找路径
 69     for (int i=head[u]; i!=-1; i=edge[i].next)
 70     {
 71         int v = edge[i].to;
 72         if (!vis[v] && dy[v] == dx[u]+1)
 73         {
 74             vis[v] = 1;
 75             if (cy[v]!=-1 && dis==dy[v])
 76                 continue;
 77             if (cy[v]==-1 || dfs(cy[v]))
 78             {
 79                 cy[v] = u;
 80                 cx[u] = v;
 81                 return 1;
 82             }
 83         }
 84     }
 85     return 0;
 86 }
 87 int Max_match ()
 88 {//得到最大匹配数目
 89     int res = 0;
 90     memset (cx, -1, sizeof(cx));
 91     //左边顶点i所匹配的右边的点
 92     memset (cy, -1, sizeof(cy));
 93     //右边顶点i所匹配的左边的点
 94     while (bfs ())
 95     {
 96         memset (vis, 0, sizeof(vis));
 97         for (int i=1; i<=n; i++)
 98             if (cx[i] == -1)
 99                 res += dfs(i);
100     }
101     return res;
102 }
103 int main ()
104 {
105     int cas, t, l = 0;
106     scanf ("%d", &cas);
107     while (cas --)
108     {
109         scanf ("%d %d", &t, &n);
110         for (int i=1; i<=n; i++)
111         {
112             scanf ("%lf %lf %lf", &p_gue[i].x, &p_gue[i].y, &p_gue[i].num);
113             p_gue[i].num *= t;
114         }
115
116         scanf ("%d", &m);
117         for (int i=1; i<=m; i++)
118             scanf ("%lf %lf", &p_umb[i].x, &p_umb[i].y);
119
120         memset (head, -1, sizeof(head));
121         tot = 0;
122         for (int i=1; i<=n; i++)
123             for (int j=1; j<=m; j++)
124             {
125                 double x = p_gue[i].x - p_umb[j].x;
126                 double y = p_gue[i].y - p_umb[j].y;
127                 double num = sqrt (x*x + y*y);
128                 if (num <= p_gue[i].num)
129                     Add (i, j);
130             }
131         printf ("Scenario #%d:\n%d\n\n", ++l, Max_match());
132     }
133     return 0;
134 }
时间: 2024-10-28 14:15:05

Hdu 3289 Rain on your Parade (二分图匹配 Hopcroft-Karp)的相关文章

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 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 (二分图匹配(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 p

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-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

hdu2389二分图之Hopcroft Karp算法

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.

HDU 3289 Cat VS Dog (二分匹配 求 最大独立集)

题意:每个人有喜欢的猫和不喜欢的狗.留下他喜欢的猫他就高心,否则不高心.问最后最多有几个人高心. 思路:二分图求最大匹配 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 #include<string> 7 #include<cmath> 8 #include<