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

题目链接

题意:有n个客人,m把雨伞,在t秒之后将会下雨,给出每个客人的坐标和每秒行走的距离,以及雨伞的位置,问t秒后最多有几个客人可以拿到雨伞?

就是求最大匹配的

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

所以只能用Hopcroft-Karp而且好像只能用邻接表来表示;

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define N 3010
#define INF 0xfffffff

int vis[N], usedx[N], usedy[N], n, m;
int dx[N], dy[N], cnt, depth, head[N];
///BFS分层时,dx[] dy[]记录点所在的层,-1表示不在分层
struct node
{
    int x, y, v;
} a[N], b[N];
struct Edge
{
    int v, next;
}e[N*N];///用邻接表
void Add(int u, int v)
{
    e[cnt].v = v;
    e[cnt].next = head[u];
    head[u] = cnt++;
}

bool Find(int u)
{
    for(int i=head[u]; i!=-1; i=e[i].next)
    {
        int v = e[i].v;
        if(!vis[v] && dx[u] == dy[v]-1)
        {
            vis[v] = 1;
            if(!usedy[v] || Find(usedy[v]))
            {
                usedy[v] = u;
                usedx[u] = v;
                return true;
            }
        }
    }
    return false;
}
bool bfs()
{
    queue<int> Q;
    depth = INF;
    memset(dx, -1, sizeof(dx));
    memset(dy, -1, sizeof(dy));
    for(int i=1; i<=n; i++)
    {
        if(!usedx[i])
        {
            dx[i] = 0;
            Q.push(i);
        }
    }
    while(!Q.empty())
    {
        int u = Q.front(); Q.pop();
        if(depth < dx[u])
            break;
        for(int j=head[u]; j!=-1; j=e[j].next)
        {
            int v = e[j].v;
            if(dy[v] == -1)
            {
                dy[v] = dx[u] + 1;
                if(!usedy[v])
                    depth = dy[v];
                else
                {
                    dx[ usedy[v] ] = dy[v] + 1;
                    Q.push( usedy[v] );
                }
            }
        }
    }
    if(depth == INF)
        return false;
    return true;
}
int main()
{
    int T, t, x, y, t0=1;
    scanf("%d", &T);
    while(T--)
    {
        cnt = 0;
        memset(head, -1, sizeof(head));
        scanf("%d%d", &t, &n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].v);
        }
        scanf("%d", &m);
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d", &x, &y);
            for(int j=1; j<=n; j++)
            {
                int d = (a[j].x-x)*(a[j].x-x)+(a[j].y-y)*(a[j].y-y);
                if(d <= a[j].v*t*a[j].v*t)
                    Add(j, i);
            }
        }
        int ans = 0;
        memset(usedx, 0, sizeof(usedx));
        memset(usedy, 0, sizeof(usedy));
        while( bfs() )
        {
            memset(vis, 0, sizeof(vis));
            for(int i=1; i<=n; i++)
            {
                if(!usedx[i] && Find(i))
                    ans++;
            }
        }
        printf("Scenario #%d:
%d

", t0++, ans);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4722191.html