# bzoj 1020 安全的航线|计算几何

2 篇文章 0 订阅

#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath> #define md#define ll long long#define inf (int) 1e9#define eps 1e-8#define Nusing namespace std;struct point { double x,y;} xian[25];struct line {point x,y;} q[1000010];struct near {point x;double dis;};const int maxn=1000000;int n,m;double ans=0;inline double sqr(double a) { return a*a;}int fcmp(double a,double b){ if (a-b>eps) return 1; if (a-b<-eps) return -1; return 0;}double dot(point a,point b) { return a.x*b.x+a.y*b.y;}bool operator ==(point a,point b) { point p=(point){a.x-b.x,a.y-b.y}; return fcmp(p.x,0)==0&&fcmp(p.y,0)==0;}double operator * (point a,point b) { return a.x*b.y-a.y*b.x;}point operator * (point a,double b) { return (point){a.x*b,a.y*b};}point operator / (point a,double b) { return (point) {a.x/b,a.y/b};}point operator - (point a,point b)  { return (point){a.x-b.x,a.y-b.y};}point operator + (point a,point b) { return (point) {a.x+b.x,a.y+b.y};}inline double len(point a) { return sqrt(a.x*a.x+a.y*a.y);}bool on (point a,point b,point c){ if (a==b||a==c) return 1; return (fcmp((a-b)*(c-b),0)==0&&fcmp(dot(a-b,a-c),0)<0);//}bool inter(point a,point b,point c,point d){ return fcmp(((b-a)*(c-a))*((b-a)*(d-a)),0)<0&&fcmp(((d-c)*(a-c))*((d-c)*(b-c)),0)<0;} struct LAND{ int tot; point a[35]; bool in(point x) {  for (int i=1;i<=tot;i++)    if (on(x,a[i],a[i+1])) return 1;  x.y+=0.1;  point p=(point){-10001,x.y+0.1};  int jiao=0;  for (int i=1;i<=tot;i++) jiao+=inter(p,x,a[i],a[i+1]);  x.y-=0.1;  return jiao&1; }}land[25];    inline double dis(point a,line b){  point p1=a-b.x,p2=b.y-b.x,p3=a-b.y,p4=b.x-b.y; if (b.x==b.y) return len(p1); if (fcmp(dot(p1,p2),0)<0) return len(p1); if (fcmp(dot(p3,p4),0)<0) return len(p3); return (p1*p2/len(p2));}inline near getit(point a,point b,point c){ point p1=a-b,p2=c-b,p3=a-c,p4=b-c; if (b==c) return (near){b,len(p1)}; if (fcmp(dot(p1,p2),0)<=0) return (near){b,len(p1)}; if (fcmp(dot(p3,p4),0)<=0) return (near){c,len(p3)}; double t=dot(p1,p2)/dot(p2,p2); point d=b+p2*t; return (near){d,len(d-a)};}  near find(point x){ for (int i=1;i<=n;i++) if (land[i].in(x)) return (near){x,0}; double mlen=inf; near xans=(near){x,inf}; for (int i=1;i<=n;i++) {  for (int j=1;j<=land[i].tot;j++)  {   near now=getit(x,land[i].a[j],land[i].a[j+1]);   if (fcmp(now.dis,xans.dis)<=0) xans=now;  } } ans=max(ans,xans.dis); return xans;} void solve(){ ans=0; int h=0,w=0;  for (int i=1;i<m;i++)  q[++w]=(line){xian[i],xian[i+1]}; for (int i=1;i<=m;i++) find(xian[i]); while (h!=w) {  h++; if (h>maxn+2) h=1;   line L=q[h];  near p1=find(L.x),p2=find(L.y);  point l=L.x,r=L.y;  while (len(l-r)>(1e-4))  {   point mid=(l+r)/2;   int bo=fcmp(len(mid-p1.x),len(mid-p2.x));   if (bo==1) r=mid;   else if (bo==0) l=r=mid;   else l=mid;  }  double nowans=max(len(l-p1.x),len(l-p2.x));  near p=find(l);  if (ans+0.004<nowans)  {   line L1=(line){L.x,l},L2=(line){l,L.y};   w++; if (w>maxn+2) w=1; q[w]=L1;   w++; if (w>maxn+2) w=1; q[w]=L2;  } }} point read() { point a; scanf("%lf%lf",&a.x,&a.y); return a;}  int main(){ //freopen("1020.in","r",stdin); freopen("1020.out","w",stdout); scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) xian[i]=read(); for (int i=1;i<=n;i++) {  scanf("%d",&land[i].tot);  for (int j=1;j<=land[i].tot;j++) land[i].a[j]=read();  land[i].a[land[i].tot+1]=land[i].a[1];//? } solve(); printf("%.2lf\n",ans); return 0;}


• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
03-11 719
03-25 554
04-20 1653
01-30 1305
03-02 1237
03-06 1913
08-17 392
02-25 124
08-13
08-13

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。