zoukankan      html  css  js  c++  java
  • [计算几何]离大海的最远点在哪里

    题意:给定一个凸多边形,求一个点使得它到各条边的距离的最小值最大。

    这本来是一道poj原题,n<=100,但是貌似精度有问题,poj死都过不去,以后再试试...

    这次做的是一道改编题,n<=200000,一组数据。

    显然可以二分答案,并且把边往里面推,但是这样的话常数太大过不了..

    但是我们发现,一条边消失是在距离超过 它和相邻的边的角平分线的交点到它的距离 的时候。所以我们可以用一个堆来模拟推进,用双向链表维护相邻的边。

    然后作为一个计算几何菜鸡,我做完感觉意识模糊...

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #define eps 1e-9
    #define ld long double
    #define MAXN 200000
    #define pa pair<ld,int> 
    #define mp(x,y) make_pair(x,y)
    using namespace std;
    //********************
    struct P{
        ld x,y;
        P(ld _x=0,ld _y=0):x(_x),y(_y){}
    }s[MAXN+5];
    struct L{P u,v;}l[MAXN+5];
    P operator+(P x,P y){return P(x.x+y.x,x.y+y.y);}
    P operator-(P x,P y){return P(x.x-y.x,x.y-y.y);}
    ld operator*(P x,P y){return x.x*y.y-y.x*x.y;}
    P operator/(P x,ld y){return P(x.x/y,x.y/y);}
    P operator*(P x,ld y){return P(x.x*y,x.y*y);}
    ld dot(P x,P y){return x.x*y.x+x.y*y.y;}
    ld dis(P x){return sqrt(x.x*x.x+x.y*x.y);}
    P operator*(L a,L b){return a.u+a.v*(b.v*(a.u-b.u)/(a.v*b.v));}
    //********************
    int n,ne[MAXN+5],la[MAXN+5];
    priority_queue<pa > q;
    bool mark[MAXN+5];
     
    L solve(L a,L b){return (L){a*b,a.v*dis(b.v)-b.v*dis(a.v)};}
     
    ld calc(int x)
    {
        P p=solve(l[la[x]],l[x])*solve(l[x],l[ne[x]]);
        //cout<<"calc"<<x<<" "<<-fabs(p*l[x].v/dis(l[x].v))<<endl;
        return -fabs((l[x].v*(p-l[x].u))/dis(l[x].v));
    }
     
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%Lf%Lf",&s[i].x,&s[i].y);
        for(int i=1;i<=n;i++)ne[i-1]=i,la[i]=i-1;
        la[1]=n,ne[n]=1;
        for(int i=1;i<=n;i++)l[i]=(L){s[i],s[i]-s[la[i]]};
        for(int i=1;i<=n;i++)q.push(mp(calc(i),i));
        for(int i=2;i<n;i++)
        {
            while(!q.empty()&&mark[q.top().second])q.pop();
            int x=q.top().second;mark[x]=1;
            la[ne[x]]=la[x];ne[la[x]]=ne[x];
            q.push(mp(calc(la[x]),la[x]));
            q.push(mp(calc(ne[x]),ne[x]));
        }
        printf("%0.8Lf",-q.top().first);
        return 0;
    }
  • 相关阅读:
    CF526D Om Nom and Necklace
    POJ2406 Power Strings
    POJ3461 Oulipo
    luogu P1341 无序字母对
    UOJ 117 欧拉回路
    骑马修栅栏
    vimdiff env.txt export.txt set.txt
    Linux自动执行任务
    消灭 Bug!推荐5款测试员不可不知的bug管理工具!
    Bugzilla使用手册及解决方案
  • 原文地址:https://www.cnblogs.com/FallDream/p/fzoj1630.html
Copyright © 2011-2022 走看看