ZOJ 3156 Taxi 二分二分图
----------
const int maxn=411; const int maxm=141011; int n,m; double x[maxn],y[maxn]; double a[maxn][maxn]; double disTo(int i,int j) { return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); } double dis[maxn*maxn]; int cnt; double T; VI g[maxn]; int from[maxn],tot; bool use[maxn]; bool match(int u) { for (int v=0;v<m;v++) { if (a[u][v]<=T&&!use[v]) { use[v]=true; if (from[v]==-1||match(from[v])) { from[v]=u; return true; } } } return false; } bool C() { memset(from,-1,sizeof from); for (int i=0;i<n;i++) { memset(use,0,sizeof use); if (!match(i)) return false; } return true; } int main(){ while (~scanf("%d%d",&n,&m)) { double V; cnt=0; for (int i=0;i<n;i++) scanf("%lf%lf",&x[i],&y[i]); for (int i=0;i<m;i++) scanf("%lf%lf",&x[n+i],&y[n+i]); scanf("%lf",&V); for (int i=0;i<n;i++) { for (int j=0;j<m;j++) { a[i][j]=disTo(i,n+j)/V; dis[cnt++]=a[i][j]; } } sort(dis,dis+cnt); int L=0,R=cnt-1; int ans=R; while (L<=R) { int M=(L+R)/2; T=dis[M]; if (C()) { ans=M; R=M-1; } else L=M+1; } printf("%.2f\n",dis[ans]); } return 0; }
---