显然是二分+最大流判定
但比较烦的是判断线段和圆及其内部是否有公共点
我的判断方法是错的,但是数据弱
目前只知道推公式分类讨论,如果有简单的方法求教
1 const inf=10000007; 2 type node=record 3 flow,po,next:longint; 4 end; 5 point=record 6 x,y:longint; 7 end; 8 9 var e:array[0..80010] of node; 10 a,b,c:array[0..205] of point; 11 can:array[0..200,0..200] of boolean; 12 g,cur,v,w,pre,p,numh,h:array[0..505] of longint; 13 q,l,r,t,ans,mid,i,j,n,m,k,len:longint; 14 ff,ch:boolean; 15 16 function dis(a,b:point):double; 17 begin 18 exit(sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))); 19 end; 20 21 function cross(a,b,c:point):double; 22 begin 23 cross:=abs((a.x-b.x)*(a.y-c.y)-(a.x-c.x)*(a.y-b.y)); 24 cross:=cross/dis(a,b); 25 end; 26 27 procedure add(x,y,f:longint); 28 begin 29 inc(len); 30 e[len].po:=y; 31 e[len].flow:=f; 32 e[len].next:=p[x]; 33 p[x]:=len; 34 end; 35 36 function sap:longint; 37 var u,i,j,tmp,q:longint; 38 begin 39 fillchar(h,sizeof(h),0); 40 fillchar(numh,sizeof(numh),0); 41 for i:=0 to t do 42 cur[i]:=p[i]; 43 u:=0; 44 sap:=0; 45 numh[0]:=t+1; 46 while h[0]<t+1 do 47 begin 48 i:=cur[u]; 49 while i<>-1 do 50 begin 51 j:=e[i].po; 52 if (e[i].flow>0) and (h[u]=h[j]+1) then 53 begin 54 pre[j]:=u; 55 cur[u]:=i; 56 u:=j; 57 if u=t then 58 begin 59 inc(sap); 60 if sap=m then exit; 61 while u<>0 do 62 begin 63 u:=pre[u]; 64 j:=cur[u]; 65 dec(e[j].flow); 66 inc(e[j xor 1].flow); 67 end; 68 end; 69 break; 70 end; 71 i:=e[i].next; 72 end; 73 if i=-1 then 74 begin 75 dec(numh[h[u]]); 76 if numh[h[u]]=0 then exit; 77 tmp:=t; 78 q:=-1; 79 i:=p[u]; 80 while i<>-1 do 81 begin 82 j:=e[i].po; 83 if e[i].flow>0 then 84 if h[j]<tmp then 85 begin 86 q:=i; 87 tmp:=h[j]; 88 end; 89 i:=e[i].next; 90 end; 91 h[u]:=tmp+1; 92 inc(numh[h[u]]); 93 cur[u]:=q; 94 if u<>0 then u:=pre[u]; 95 end; 96 end; 97 end; 98 99 function check(s:longint):boolean; 100 var q,i,j:longint; 101 begin 102 fillchar(p,sizeof(p),255); 103 len:=-1; 104 q:=0; 105 for i:=1 to n do 106 begin 107 add(0,i,s div w[i]+1); 108 add(i,0,0); 109 if s div w[i]*w[i]>q then q:=s div w[i]*w[i]; 110 end; 111 for i:=1 to m do 112 begin 113 add(i+n,t,1); 114 add(t,i+n,0); 115 for j:=1 to n do 116 if can[i,j] then 117 begin 118 add(j,i+n,1); 119 add(i+n,j,0); 120 end; 121 end; 122 if sap=m then 123 begin 124 ans:=q; 125 exit(true); 126 end 127 else exit(false); 128 end; 129 130 begin 131 readln(n,m,k); 132 for i:=1 to n do 133 begin 134 readln(a[i].x,a[i].y,v[i],w[i]); 135 if w[i]>r then r:=w[i]; 136 end; 137 for i:=1 to m do 138 readln(b[i].x,b[i].y); 139 for i:=1 to k do 140 readln(c[i].x,c[i].y,g[i]); 141 for i:=1 to m do 142 begin 143 ch:=false; 144 for j:=1 to n do 145 if dis(b[i],a[j])<=v[j] then 146 begin 147 ff:=true; 148 for q:=1 to k do 149 if cross(b[i],a[j],c[q])<g[q] then 150 begin 151 ff:=false; 152 break; 153 end; 154 if ff then 155 begin 156 can[i,j]:=true; 157 ch:=true; 158 end; 159 end; 160 161 if not ch then 162 begin 163 writeln(-1); 164 halt; 165 end; 166 end; 167 t:=n+m+1; 168 l:=0; 169 r:=r*m; 170 while l<=r do 171 begin 172 mid:=(l+r) shr 1; 173 if check(mid) then r:=ans-1 else l:=mid+1; 174 end; 175 writeln(ans); 176 end.