HDU 2389 Rain on your Parade(Hopcroft-Carp算法模板)

来源:互联网 发布:五子棋人工智能算法 编辑:程序博客网 时间:2024/05/16 04:52

题目地址:点击打开链接


题意:有n个人m把伞,在t秒后要下雨,给出每个人和伞的坐标和每个人走路的速度,问你在t秒内最多能有几个人能拿

到伞(每把伞只能一个人用)。n,m<=3000。


匈牙利算法的时间复杂度是O(n*E),这题的边的数量达到了3000*3000,所以用匈牙利肯定会T,Hopcroft-Carp的时间

复杂度是O(sqrt(n)*E).


还没能理解Hopcroft-Carpz的原理,先用着模板吧。


代码:

#include<iostream>#include<cstdio>#include<queue>#include<cstring>#include<vector>using namespace std;/* ******************************* * 二分图匹配(Hopcroft-Carp算法) * 复杂度O(sqrt(n)*E) * 邻接表存图,vector实现 * vector先初始化,然后假如边 * uN 为左端的顶点数,使用前赋值(点编号1开始) */const int maxn = 3e3+5;const int INF = 0x3f3f3f3f;vector<int> g[maxn];int uN;int Mx[maxn], My[maxn];int dx[maxn], dy[maxn];int dis;bool vis[maxn];bool searchP(){    queue<int> q;    dis = INF;    memset(dx, -1, sizeof(dx));    memset(dy, -1, sizeof(dy));    for(int i = 1; i <= uN; i++)    {        if(Mx[i] == -1)        {            q.push(i);            dx[i] = 0;        }    }    while(!q.empty())    {        int u = q.front();        q.pop();        if(dx[u] > dis) break;        int sz = g[u].size();        for(int i = 0; i < sz; i++)        {            int v = g[u][i];            if(dy[v] == -1)            {                dy[v] = dx[u]+1;                if(My[v] == -1) dis = dy[v];                else                {                    dx[My[v]] = dy[v]+1;                    q.push(My[v]);                }            }        }    }    return dis != INF;}bool dfs(int u){    int sz = g[u].size();    for(int i = 0; i < sz; i++)    {        int v = g[u][i];        if(!vis[v] && dy[v] == dx[u]+1)        {            vis[v] = 1;            if(My[v] != -1 && dy[v] == dis) continue;            if(My[v] == -1 || dfs(My[v]))            {                My[v] = u;                Mx[u] = v;                return true;            }        }    }    return false;}int MaxMatch(){    int res = 0;    memset(Mx, -1, sizeof(Mx));    memset(My, -1, sizeof(My));    while(searchP())    {        memset(vis, 0, sizeof(vis));        for(int i = 1; i <= uN; i++)            if(Mx[i] == -1 && dfs(i))                res++;    }    return res;}/******************************************************/struct Point{    int x, y, s;    void input1()    {        scanf("%d%d%d", &x, &y, &s);    }    void input2()    {        scanf("%d%d", &x, &y);    }};Point p1[maxn], p2[maxn];int dis2(Point a, Point b){    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}int main(void){    int T, t, ca = 1, n, m;    cin >> T;    while(T--)    {        for(int i = 0; i < maxn; i++)            g[i].clear();        scanf("%d%d", &t, &n);        for(int i = 1; i <= n; i++)            p1[i].input1();        scanf("%d", &m);        for(int i = 1; i <= m; i++)            p2[i].input2();        uN = n;        for(int i = 1; i <= n; i++)            for(int j = 1; j <= m; j++)                if(dis2(p1[i], p2[j]) <= p1[i].s*p1[i].s*t*t)                    g[i].push_back(j);        printf("Scenario #%d:\n%d\n\n", ca++, MaxMatch());    }    return 0;}


1 0
原创粉丝点击