显然是二分+最大流判定
但比较烦的是判断线段和圆及其内部是否有公共点
我的判断方法是错的,但是数据弱
目前只知道推公式分类讨论,如果有简单的方法求教

  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.
View Code

 

posted on 2015-02-25 19:27  acphile  阅读(189)  评论(0编辑  收藏  举报