Hdu 2389 二分匹配

题目链接

Rain on your Parade

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Java/Others)
Total Submission(s): 2644    Accepted Submission(s): 823

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

题目也是很裸的最大匹配问题,匈牙利算法复杂度太高(对于这题而言, O(n*m)), 而Hopcroft-Karp算法复杂度只有O(sqrt(n)*m).关于算法的具体实现,

网上百度一大推。1A......:D

Accepted Code:

  1 /*************************************************************************
  2     > File Name: 2389.cpp
  3     > Author: Stomach_ache
  4     > Mail: [email protected]
  5     > Created Time: 2014年08月01日 星期五 22时08分50秒
  6     > Propose: Hopcroft-Karp
  7  ************************************************************************/
  8 #include <queue>
  9 #include <cmath>
 10 #include <string>
 11 #include <cstdio>
 12 #include <vector>
 13 #include <fstream>
 14 #include <cstring>
 15 #include <iostream>
 16 #include <algorithm>
 17 using namespace std;
 18
 19 const int maxn = 3002;
 20 const int INF = 0x3f3f3f3f;
 21 int cx[maxn], cy[maxn];
 22 int dx[maxn], dy[maxn];
 23 bool mark[maxn];
 24 vector<int> next[maxn];
 25 int n, m;
 26 struct node {
 27       int x, y, s;
 28 }g[maxn];
 29
 30 int dist(int x1, int y1, int x2, int y2) {
 31       return (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2);
 32 }
 33
 34 int searchPath() {
 35       memset(dx, -1, sizeof(dx));
 36     memset(dy, -1, sizeof(dy));
 37     queue<int> Q;
 38     for (int i = 1; i <= m; i++) if (cx[i] == -1) {
 39           dx[i] = 0;
 40         Q.push(i);
 41     }
 42     int dist = INF;
 43     while (!Q.empty()) {
 44           int u = Q.front(); Q.pop();
 45         if (dx[u] > dist) break;
 46         for (int i = 0; i < (int)next[u].size(); i++) {
 47               int v = next[u][i];
 48               if (dy[v] == -1) {
 49                   dy[v] = dx[u] + 1;
 50                 if (cy[v] == -1) {
 51                       dist = dy[v];
 52                 } else {
 53                       dx[cy[v]] = dy[v] + 1;
 54                     Q.push(cy[v]);
 55                 }
 56             }
 57         }
 58     }
 59     return dist != INF;
 60 }
 61
 62 int findPath(int u) {
 63       for (int i = 0; i < (int)next[u].size(); i++) {
 64           int v = next[u][i];
 65         if (!mark[v] && dy[v] == dx[u] + 1) {
 66               mark[v] = true;
 67             if (cy[v] == -1 || findPath(cy[v])) {
 68                   cy[v] = u;
 69                 cx[u] = v;
 70                 return 1;
 71             }
 72         }
 73     }
 74     return 0;
 75 }
 76
 77 int MaxMatch() {
 78       int res = 0;
 79       memset(cx, -1, sizeof(cx));
 80     memset(cy, -1, sizeof(cy));
 81     while (searchPath()) {
 82           memset(mark, false, sizeof(mark));
 83         for (int i = 1; i <= m; i++) {
 84               if (cx[i] == -1) {
 85                   res += findPath(i);
 86             }
 87         }
 88     }
 89     return res;
 90 }
 91
 92 int main(void) {
 93       int T, cas = 1;
 94     scanf("%d", &T);
 95     while (T--) {
 96           int t;
 97           scanf("%d", &t);
 98         scanf("%d", &m);
 99         for (int i = 1; i <= m; i++) {
100               next[i].clear();
101               scanf("%d %d %d", &g[i].x, &g[i].y, &g[i].s);
102         }
103         scanf("%d", &n);
104         for (int i = 1; i <= n; i++) {
105               int x, y;
106             scanf("%d %d", &x, &y);
107             for (int j = 1; j <= m; j++) {
108                   if (t*t*g[j].s*g[j].s >= dist(x, y, g[j].x, g[j].y)) {
109                       next[j].push_back(i);
110                 }
111             }
112         }
113         printf("Scenario #%d:\n%d\n\n", cas++, MaxMatch());
114     }
115
116     return 0;
117 }

Hdu 2389 二分匹配,布布扣,bubuko.com

时间: 2024-10-29 05:19:33

Hdu 2389 二分匹配的相关文章

hdu 4169 二分匹配最大独立集 ***

题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #incl

hdu 5093 二分匹配

/* 题意:给你一些冰岛.公共海域和浮冰,冰岛可以隔开两个公共海域,浮冰无影响 求选尽可能多的选一些公共海域点每行每列仅能选一个. 限制条件:冰山可以隔开这个限制条件.即*#*可以选两个 预处理: ***** **#*# ***** 可以按行转化 ***** **#oo ooo*# ***** 按列转化 ***o**o **ooooo oooo*oo **o**o* 因为每行每列顶多可以增加50 所以总共最多2500*2500的矩阵 然后直接二分匹配即可 */ #include<stdio.h>

Battle ships HDU - 5093二分匹配

Battle shipsHDU - 5093 题目大意:n*m的地图,*代表海洋,#代表冰山,o代表浮冰,海洋上可以放置船舰,但是每一行每一列只能有一个船舰(类似象棋的車),除非同行或者同列的船舰中间有冰山挡着,问最多能放多少个船舰? 之前做过一个放置炮的,那时数据小直接暴力加搜索就A了,然而这题暴力搜索的话,直接了当的TLE,没办法只好去学新东西了.二分图这个概念只有在之前的题目中做过匈牙利的板子题,可是具体概念和思路并不了解,这题也正好提醒了我去深入了解.但最近需要做的事情较大,一直想整理的

hdu 4685 二分匹配+强连通分量

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<vector> 5 #include<stack> 6 #include<algorithm> 7 using namespace std; 8 9 const int maxn =

HDU 3729 二分匹配匈牙利算法

I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1482    Accepted Submission(s): 740 Problem Description After this year’s college-entrance exam, the teacher did a survey in

H - Prince and Princess - HDU 4685(二分匹配+强连通分量)

题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备匹配,所以需要添加一些点使他们成为完备匹配才能求出来的环是完整的,比如第二组数据: 1 2   2 1 2 如果不添加虚拟点做成匹配,只会匹配成功一个,这样就找不出来环了,所以需要添加虚拟的王子和公主,虚拟的王子喜欢所有的公主,虚拟的公主被所有的王子喜欢,注意都是王子喜欢公主的,公主没有选择喜欢的权

HDU 5090 二分匹配

Game with Pearls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 172    Accepted Submission(s): 103 Problem Description Tom and Jerry are playing a game with tubes and pearls. The rule of the g

Treasure Hunting (hdu 3468 二分匹配+bfs最短路径)

Treasure Hunting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1509    Accepted Submission(s): 393 Problem Description Do you like treasure hunting? Today, with one of his friend, iSea is on

HDU 2603 二分匹配

#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std; const int N = 510;int maps[N][N], visit[N], used[N];int n, m;bool Find(int u)//女生u{ for(int