F - Rain on your Parade - hdu 2389(二分图匹配,Hk算法)

题意:给一些人和一些伞的坐标,然后每个人都有一定的速度,还有多少时间就会下雨,问最多能有多少人可以拿到伞。

分析:题意很明确,可以用每个人和伞判断一下是否能够达到,如果能就建立一个联系。不过这道题的数据还是挺大的,第一次使用的匈牙利算法果断的TLE了,然后就百度了一下发现有一个 Hopcroft-Karp算法 不过这个算法网上描述的很少,而且都说的比较含糊不清,不过幸好搜到一个比较不错的课件,看了一上午总算有些明白怎么回事,以前是寻找一个增广路,这个是寻找所有的增广路,并且使用BFS进行分层,看起来比较高大上,虽然我还是不明白怎么减少的复杂度(提交确实不不超时了).......后面做题在慢慢理解吧

课件连接

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

const int MAXN = 3005;
const int oo = 1e9+7;

struct point{int x, y, v;}p[MAXN], um;
bool OK(point a, point b, int v)
{///判断两点是否在合法范围内,也就是下雨前能否达到
    int len = (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);

if(len > v*v)
        return false;
    return true;
}

struct Edge{int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt;
void AddEdge(int u, int v)
{///邻接表,点比较多,不好开邻接矩阵
    e[cnt].v = v;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
}

bool used[MAXN];
int Mx[MAXN], My[MAXN];///记录的所匹配的端点,0表示未匹配
int dx[MAXN], dy[MAXN];///BFS分层时,记录点所在的层,-1表示不在分层
int Nx, Ny, depth;///Nx个人,Ny把雨伞, depth记录分层的深度

bool BFS()///如果发现y这边有增广路,返回1,否则返回0
{
    queue<int> Q; depth = oo;

memset(dx, -1, sizeof(dx));
    memset(dy, -1, sizeof(dy));

for(int i=1; i<=Nx; i++)
    {
        if( Mx[i] == false )
        {
            dx[i] = 0;
            Q.push(i);
        }
    }

while(Q.size())
    {
        int x = Q.front(); Q.pop();
        if(dx[x] > depth) break;///已经找到了增广路,不必寻找下层

for(int j=Head[x]; j!=-1; j=e[j].next)
        {
            int y = e[j].v;

if( dy[y] == -1 )
            {
                dy[y] = dx[x] + 1;

if(My[y] == false)
                    depth = dy[y];
                else
                {
                    dx[ My[y] ] = dy[y] + 1;
                    Q.push( My[y] );
                }
            }
        }
    }

if( depth == oo )
        return false;
    return true;
}
bool Find(int i)
{
    for(int j=Head[i]; j!=-1; j=e[j].next)
    {
        int v = e[j].v;

if( !used[v] && dx[i] == dy[v]-1)
        {
            used[v] = true;

if( My[v] && dy[v] == depth )
                continue;///不会在下一层,因为还没有对下层进行增广

if( !My[v] || Find( My[v] ) )
            {
                My[v] = i;
                Mx[i] = v;
                return true;
            }
        }
    }

return false;
}

int Karp()
{
    int ans = 0;
    memset(Mx, false, sizeof(Mx));
    memset(My, false, sizeof(My));

while( BFS() == true )
    {///如果还存在增广路
        memset(used, false, sizeof(used));
        for(int i=1; i<=Nx; i++)
        {
            if( !Mx[i] && Find(i) == true )
                ans++;
        }
    }

return ans;
}

int main()
{
    int T, t=1;

scanf("%d", &T);

while(T--)
    {
        int i, j, time;

scanf("%d%d", &time, &Nx);

memset(Head, -1, sizeof(Head));
        cnt = 0;

for(i=1; i<=Nx; i++)
            scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].v);

scanf("%d", &Ny);

for(i=1; i<=Ny; i++)
        {
            scanf("%d%d", &um.x, &um.y);

for(j=1; j<=Nx; j++)
            {
                if( OK(p[j], um, p[j].v*time) )
                    AddEdge(j, i);
            }
        }

int ans = Karp();

printf("Scenario #%d:\n", t++);
        printf("%d\n\n", ans);
    }

return 0;

}

时间: 2024-09-27 10:09:03

F - Rain on your Parade - hdu 2389(二分图匹配,Hk算法)的相关文章

(匹配 Hopcroft-Karp算法)Rain on your Parade -- Hdu --2389

链接: http://acm.hdu.edu.cn/showproblem.php?pid=2389 不能用匈牙利,会TEL的,用Hopcroft-Karp Hopcroft-Karp课件 以前是寻找一个增广路,这个是寻找所有的增广路,并且使用BFS进行分层 代码: #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<queue> #in

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

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

USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)

The Perfect StallHal Burch Farmer John completed his new barn just last week, complete with all the latest milking technology. Unfortunately, due to engineering problems, all the stalls in the new barn are different. For the first week, Farmer John r

HDU1507 Uncle Tom&#39;s Inherited Land* 二分图匹配 匈牙利算法 黑白染色

原文链接http://www.cnblogs.com/zhouzhendong/p/8254062.html 题目传送门 - HDU1507 题意概括 有一个n*m的棋盘,有些点是废的. 现在让你用1*2的矩形覆盖所有的不废的点,并且不重叠,问最多可以覆盖多少个1*2的矩形,输出方案,有SPJ. 输入描述: 多组数据,每组首先两个数n,m(如果n和m为0,则结束程序) 然后给出k 然后给出k个二元组(x,y)表示废点的坐标. 题解 按照前两片博文的算法已经不行了,因为方案不对了. 所以我们要进行

训练指南 UVALive - 4043(二分图匹配 + KM算法)

layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图匹配 - 图论 - 训练指南 Ants UVALive - 4043 题意 给你n个白点和n个黑点的平面坐标,要求用n条不相交的线连起来,每条线段连一个白点和黑点,每个点连一条线,也就是匹配.让你输出第i个白点所对应的黑点. 思路 二分图完美匹配问题.但是题目

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

题意:一些女的和一些男的有好感,有好感的能一起坐过山车,问最多能组成多少对 hdu 11 页上少有的算法题,二分图匹配问题,匈牙利算法,对于每一个汉子,看和他有好感的妹子有没有配对了,没有配对过就可以成功配对,若已经配对过了,就看那个妹子所配对的汉子能不能再找个没有配对的妹子,如果可以就拆散当前配对重组配对,否则就不能拆:如果找完所有有好感的妹子仍然没能配对成功,那这个汉子就注定孤独一生了``` 1 #include<stdio.h> 2 #include<string.h> 3

hdu 1281 二分图匹配

题目:在保证尽量多的“车”的前提下,棋盘里有些格子是可以避开的,也就是说,不在这些格子上放车,也可以保证尽量多的“车”被放下.但是某些格子若不放子,就 无法保证放尽量多的“车”,这样的格子被称做重要点.Gardon想让小希算出有多少个这样的重要点,你能解决这个问题么? 二分图匹配居然还能这么用!!!脑洞大开啊!!! 思路:把棋盘的行x看成二分图左边的点,列y看成二分图右边的点,那么就把可以放车的位置看成是一条边,而二分图的最大匹配中x互不相同,y 互不相同,所以每个匹配都是不同行不同列,所以最大