bzoj 3035 二分答案+二分图最大匹配
大原来做的一道题,偷懒直接粘的原来的程序
http://www.cnblogs.com/BLADEVIL/p/3433520.html
/************************************************************** Problem: 3035 User: BLADEVIL Language: Pascal Result: Accepted Time:240 ms Memory:4216 kb ****************************************************************/ //By BLADEVIL var n, m, t2, v :longint; t1 :real; dis :array[0..100,0..100] of real; ans :real; pre, other, last :array[0..200100] of longint; link :array[0..100] of longint; flag :array[0..100] of boolean; x1, x2, y1, y2 :array[0..100] of longint; l :longint; len :array[0..200100] of real; procedure init; var i, j :longint; begin read(n,m,t1,t2,v); for i:=1 to m do read(x2[i],y2[i]); for i:=1 to n do read(x1[i],y1[i]); t1:=t1/60; for i:=1 to n do for j:=1 to m do dis[i,j]:=sqrt((x1[i]-x2[j])*(x1[i]-x2[j])+(y1[i]-y2[j])*(y1[i]-y2[j])); end; procedure connect(x,y:longint; z:real); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; len[l]:=z; end; function find(i:longint):boolean; var q, p :longint; begin q:=last[i]; while q<>0 do begin p:=other[q]; if (not flag[p]) then begin flag[p]:=true; if (link[p]=0) or (find(link[p])) then begin link[p]:=i; exit(true); end; end; q:=pre[q]; end; exit(false); end; procedure judge(low,high:real); var mid :real; tot :longint; i, j, ll :longint; k :longint; count :longint; begin if high<low then exit; fillchar(last,sizeof(last),0); fillchar(link,sizeof(link),0); tot:=0; l:=1; mid:=(low+high)/2; k:=trunc(((mid-t1)/(t1+t2))+1); for i:=1 to n do for ll:=1 to k do begin inc(tot); for j:=1 to m do if (((mid-t1)-(ll-1)*(t1+t2))*v)>=dis[i,j] then connect(tot,j,dis[i,j]/v+(ll-1)*(t1+t2)+t1); end; count:=0; for i:=1 to tot do begin fillchar(flag,sizeof(flag),false); if find(i) then inc(count); end; if (high-low<1e-8) then if count>=m then begin ans:=mid; end else exit; if count>=m then begin ans:=mid; judge(low,mid-1e-8); end else judge(mid+1e-8,high); end; procedure main; begin judge(1,30000); writeln(ans:0:6); end; begin init; main; end.