Rain on your Parade HDU - 2389(二分+HK)

匈牙利算法复杂度o(VE),HK复杂度(sqrt(v)E),这题建图就要3000*3000,用二分优化完再匈牙利爆栈了,只能用HK了,这个模板原来用过,发现ny就没有用,nx是x方的点数

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<ctime>
#include<algorithm>
#define eps 1e-14
#define pi acos(-1)
#define ll long long
#define RD T*(rand()*2-RAND_MAX)
#define Drand (long double)rand()/RAND_MAX
#define LINF 1e18
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=5000;
const int mod=1e4+7;

int m,n,rain;
int xx[maxn];

struct Guest
{
    int x,y,v;
}gu[maxn],um[maxn];


int cmp(Guest a,Guest b)
{
    return a.x<b.x;
}

int cx[maxn];
int cy[maxn];
int nx;
int dx[maxn];
int dy[maxn];
int dis;
int bmask[maxn];
int head[maxn],tot=0;
struct Edge
{
    int v,nex;
    Edge(){}
    Edge(int v,int nex):v(v),nex(nex){}
}bmap[3001*3001];

void add_edge(int u,int v)
{
    bmap[tot].nex=head[u];
    bmap[tot].v=v;
    head[u]=tot++;
}

bool searchpath()
{
    queue<int>Q;
    dis=INF;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));
    for(int i=1;i<=nx;i++)
    {
        if(cx[i]==-1)
        {
            Q.push(i);
            dx[i]=0;
        }
    }
    while(!Q.empty())
    {
        int u=Q.front();
        Q.pop();
        if(dx[u]>dis) break;
        for(int i=head[u];i!=-1;i=bmap[i].nex)
        {
            int v=bmap[i].v;
            if(dy[v]==-1)
            {
                dy[v]=dx[u]+1;
                if(cy[v]==-1)dis=dy[v];
                else
                {
                    dx[cy[v]]=dy[v]+1;
                    Q.push(cy[v]);
                }
            }
        }
    }
    return dis!=INF;
}

int findpath(int u)
{
    for(int i=head[u];i!=-1;i=bmap[i].nex)
    {
        int v=bmap[i].v;
        if(bmask[v]==0 && dy[v]==dx[u]+1)
        {
            bmask[v]=1;
            if(cy[v]!=-1 && dis==dy[v])continue;
            if(cy[v]==-1 || findpath(cy[v]))
            {
                cx[u]=v;
                cy[v]=u;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res=0;
    memset(cx,-1,sizeof(cx));
    memset(cy,-1,sizeof(cy));
    while(searchpath())
    {
        memset(bmask,0,sizeof(bmask));
        for(int i=1;i<=nx;i++)
        {
            if(cx[i]==-1)
            {
                res+=findpath(i);
            }
        }
    }
    return res;
}

int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int t,cas=1;
    scanf("%d",&t);
    while(t--){
        memset(head,-1,sizeof head);
        tot=0;
        scanf("%d",&rain);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)scanf("%d%d%d",&gu[i].x,&gu[i].y,&gu[i].v);
        scanf("%d",&n);
        nx=m;
        for(int i=1;i<=n;i++)scanf("%d%d",&um[i].x,&um[i].y);
        sort(um+1,um+1+n,cmp);
        for(int i=1;i<=n;i++)xx[i]=um[i].x;
        for(int i=1;i<=m;i++){
            int l=lower_bound(xx+1,xx+1+n,gu[i].x-rain*gu[i].v)-xx;
            int r=lower_bound(xx+1,xx+1+n,gu[i].x+rain*gu[i].v)-xx;
            for(int j=l;j<=r && j<=n;j++){
                int x=um[i].x,y=um[i].y;
                if((gu[j].x-x)*(gu[j].x-x)+(gu[j].y-y)*(gu[j].y-y)
                   <=gu[j].v*gu[j].v*rain*rain)add_edge(i,j);
            }
        }
        printf("Scenario #%d:\n%d\n\n",cas++,MaxMatch());
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值