hdu2389 Rain on your Parade【二分图最大匹配-HK算法】

来源:互联网 发布:galgame汉化软件 编辑:程序博客网 时间:2024/05/16 04:44

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2389
题意:有m个宾客,n把雨伞,预计时间t后将会下大雨,告诉你每个宾客的位置和速度,每把雨伞的位置,问你最多几个宾客不淋雨
解析:很显然的二分图匹配,不过图规模有点大,所以匈牙利这种O(VE)的估计就过不了,而Hopcroft-Carp这种O(sqrt(v)*E)的就不会超时,就当测试下板子

#include <bits/stdc++.h>#define sqr(x)  ((x)*(x))using namespace std;const int maxn = 4005;const int inf = 0x7fffffff;typedef long long ll;struct node{    int x,y,s;}a[maxn],b[maxn];int g[maxn][maxn];int mx[maxn],my[maxn];int dx[maxn],dy[maxn],dis;int vis[maxn];int nx,ny;bool bfs(){    queue<int>q;    dis = inf;    memset(dx,-1,sizeof(dx));    memset(dy,-1,sizeof(dy));    for(int i=0;i<nx;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;        for(int v = 0;v<ny;v++)        {            if(g[u][v]&&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){    for(int v = 0;v<ny;v++)    {        if(!vis[v] && g[u][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 hk(){    int res = 0;    memset(mx,-1,sizeof(mx));    memset(my,-1,sizeof(my));    while(bfs())    {        memset(vis,0,sizeof(vis));        for(int i=0;i<nx;i++)        {            if(mx[i]==-1 && dfs(i))                res++;        }    }    return res;}bool judge(int i,int j,int t){    long long dis = sqr((ll)a[i].x-b[j].x)+sqr((ll)a[i].y-b[j].y);    long long tmp = sqr((ll)a[i].s)*t*t-dis;    return tmp>=0;}int main(void){    int t,time,case_t = 1;    scanf("%d",&t);    while(t--)    {        int m,n;        memset(g,0,sizeof(g));        scanf("%d %d",&time,&m);        for(int i=0;i<m;i++)            scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].s);        scanf("%d",&n);        for(int i=0;i<n;i++)            scanf("%d %d",&b[i].x,&b[i].y);        for(int i=0;i<m;i++)        {            for(int j=0;j<n;j++)            {                if(judge(i,j,time))                    g[i][j] = 1;            }        }        nx = m,ny = n;        printf("Scenario #%d:\n%d\n\n",case_t++,hk());    }    return 0;}
阅读全文
0 0