zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    docker入门(一)
    netstat命令
    grep的小技巧
    gd库的安装
    jar命令的用法详解
    关于awk的范围模式功能问题
    更换文本中第二次出现的字符串内容
    awk打印第n个参数到最后一个技巧/将n行组成一列
    awk -f program.file 功能使用
    shell的变量处理
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4722191.html
Copyright © 2011-2022 走看看