zoukankan      html  css  js  c++  java
  • F

    题意:给一些人和一些伞的坐标,然后每个人都有一定的速度,还有多少时间就会下雨,问最多能有多少人可以拿到伞。
    分析:题意很明确,可以用每个人和伞判断一下是否能够达到,如果能就建立一个联系。不过这道题的数据还是挺大的,第一次使用的匈牙利算法果断的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, -1sizeof(dx));
        memset(dy, -1sizeof(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, falsesizeof(Mx));
        memset(My, falsesizeof(My));

        while( BFS() == true )
        {///如果还存在增广路
            memset(used, falsesizeof(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, -1sizeof(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: ", t++);
            printf("%d ", ans);
        }

        return 0; 

    }

  • 相关阅读:
    双指针法
    secureCRT安装与激活
    [Python之路] Python各类常用库整理
    [工具] Atom Markdown编辑器
    [Python之路] object类中的特殊方法
    [Python自学] Flask框架 (5) (DBUtils数据库链接池、wtforms)
    [Python自学] Flask框架 (4) (Request&Session上下文管理、redis保存session、App&g上下文管理)
    [刷题] Leetcode算法 (2020-3-1)
    [工具] Window10搭建Django开发环境
    [算法] 动态规划 (1) (工作最优收入)
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4699173.html
Copyright © 2011-2022 走看看