#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> using namespace std; const int inf=0x3f3f3f3f; const int maxn=3003; const int maxm=maxn*maxn; int xlink[maxn],ylink[maxn]; int dx[maxn],dy[maxn]; int head[maxn]; int dis; bool vis[maxn]; int n,m,t; int ecnt; struct Edge{ int v,next; Edge(){} Edge(int v,int next):v(v),next(next){} }e[maxm]; struct node{ double x,y,v; }p[maxn],u[maxn]; double getdis(node a,node b){ double dx=a.x-b.x; double dy=a.y-b.y; return sqrt(dx*dx+dy*dy); } void add(int u,int v){ e[ecnt]=Edge(v,head[u]); head[u]=ecnt++; } bool bfs(){ memset(dx,-1,sizeof dx); memset(dy,-1,sizeof dy); queue<int>q; for(int i=0;i<n;i++){ if(xlink[i]==-1){ dx[i]=0; q.push(i); } } dis=inf; while(!q.empty()){ int u=q.front();q.pop(); if(dx[u]>dis)break; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(dy[v]==-1){ dy[v]=dx[u]+1; if(ylink[v]==-1)dis=dy[v]; else{ dx[ylink[v]]=dy[v]+1; q.push(ylink[v]); } } } } return dis!=inf; } int find(int u){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(vis[v])continue; if(dy[v]==dx[u]+1){ vis[v]=1; if(ylink[v]!=-1&&dy[v]==dis)continue; if(ylink[v]==-1||find(ylink[v])){ ylink[v]=u; xlink[u]=v; return 1; } } } return 0; } int hk(){ int ans=0; while(bfs()){ memset(vis,0,sizeof vis); for(int i=0;i<n;i++)if(xlink[i]==-1){ ans+=find(i); } } return ans; } void solve(){ scanf("%d%d",&t,&n); for(int i=0;i<n;i++)scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].v); scanf("%d",&m); for(int i=0;i<m;i++)scanf("%lf%lf",&u[i].x,&u[i].y); memset(head,-1,sizeof head); memset(xlink,-1,sizeof xlink); memset(ylink,-1,sizeof ylink); ecnt=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++){ double dis=getdis(p[i],u[j]); double d=p[i].v*t; if(d>=dis)add(i,j); } printf("%d\n\n",hk()); } int main() { // freopen("in","r",stdin); int T,cas=1; cin>>T; while(T--){ printf("Scenario #%d:\n",cas++); solve(); } return 0; }
hdu 2389 Rain on your Parade(二分图HK算法)
原文:http://www.cnblogs.com/wshh/p/4295929.html