HDOJ 2389 - Hopcroft-Carp模板二分图最大匹配

来源:互联网 发布:算法设计与分析第五章 编辑:程序博客网 时间:2024/06/05 00:18

             题意

                     在开一个Party...被告知t分钟后会下雨...告诉每个人的坐标以及其跑步的速度..告诉每把伞的坐标..问最多能让多少个人躲雨成功...

             题解:

                     根据距离速度的关系构边.....然后跑二分图最大匹配匈牙利会超时...第一次发现还有个Hopcroft-Carp的方法...直接拿来当模板了...


Program:

#include<iostream>#include<stdio.h>#include<algorithm>#include<cmath>#include<stack>#include<string.h>#include<queue>#define ll long long#define esp 1e-5#define MAXN 3005#define MAXM 50000005#define oo 100000007using namespace std;struct node{       int x,y,sp;       bool operator <(node a) const       {              return x<a.x;       } }P[MAXN],U[MAXN];int n,match[MAXN];bool g[MAXN][MAXN],used[MAXN];   int Mx[MAXN],My[MAXN],Nx,Ny;int dx[MAXN],dy[MAXN],dis;bool vst[MAXN];//------------Hopcroft-Carp模板-----g[][]存图,记得初始化Nx,Ny--------- bool searchP(){      queue<int>Q;      dis=oo;      memset(dx,-1,sizeof(dx));      memset(dy,-1,sizeof(dy));      for(int i=1;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=1;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!=oo;    }    bool DFS(int u){       for(int v=1;v<=Ny;v++)           if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1)           {                vst[v]=1;                if(My[v]!=-1&&dy[v]==dis) continue;                if(My[v]==-1||DFS(My[v]))                {                    My[v]=u;                    Mx[u]=v;                    return 1;                }               }         return 0;  }int MaxMatch(){       int res=0;       memset(Mx,-1,sizeof(Mx));       memset(My,-1,sizeof(My));       while(searchP())       {            memset(vst,0,sizeof(vst));            for(int i=1;i<=Nx;i++)             if(Mx[i]==-1&&DFS(i))  res++;       }       return res;   }    //-------------Hopcroft-Carp------------------bool ok(int a,int b,int t){        int dis=(P[a].x-U[b].x)*(P[a].x-U[b].x)+(P[a].y-U[b].y)*(P[a].y-U[b].y);       return dis<=(t*P[a].sp)*(t*P[a].sp);}int main(){       int T,m,i,j,t,cases;        freopen("input.txt","r",stdin);       freopen("output.txt","w",stdout);        scanf("%d",&T);       for (cases=1;cases<=T;cases++)       {                  scanf("%d%d",&t,&n);                 for (i=1;i<=n;i++)                    scanf("%d%d%d",&P[i].x,&P[i].y,&P[i].sp);                 scanf("%d",&m);                 for (i=1;i<=m;i++) scanf("%d%d",&U[i].x,&U[i].y);                  sort(P+1,P+1+n),sort(U+1,U+1+n);                  memset(g,0,sizeof(g));                 for (i=1;i<=n;i++)                     for (j=1;j<=m;j++)                       if (ok(i,j,t)) g[i][j]=true;                    Nx=n,Ny=m;                 printf("Scenario #%d:\n%d\n\n",cases,MaxMatch());       }       return 0;}