BZOJ3911: SGU383 Caravans

来源:互联网 发布:花店管理系统数据库 编辑:程序博客网 时间:2024/06/14 14:54

这才是正宗的三角剖分。。。。
原来的是什么玩意。。。
三角剖分后求出MST 然后求LCA即可
终于把这个坑填好了啊QwQ

#include<cstdio>#include<iostream>#include<set>#include<algorithm>#include<cmath>#include<queue>using namespace std;#define New(a,b) __typeof__(b) a=(b)#define x first#define y second#define ld double const    double eps=1e-8;struct point{    ld x,y;    point(){}    point(ld x,ld y):x(x),y(y){}    inline point operator+(point z){return point(x+z.x,y+z.y);}    inline point operator-(point z){return point(x-z.x,y-z.y);}    inline point operator*(ld z){return point(x*z,y*z);}    inline point operator/(ld z){return point(x/z,y/z);}    inline ld operator*(point z){return x*z.x+y*z.y;}    inline ld operator^(point z){return x*z.y-y*z.x;}    inline bool operator<(point z)const{return abs(x-z.x)<eps?y<z.y:x<z.x;}};int n;point p[100001];ld swp,curx;struct pr{    int x,y;    pr(){};    pr(int x,int y):x(x),y(y){}    inline ld get_y(ld swp)const    {        if(y==-1)return curx;        point u=(p[y]+p[x])/2,v=p[y]-p[x];        v=point(v.y,-v.x);        ld a=v*v-v.x*v.x,b=2*((u-p[x])*v-(u.x-swp)*v.x),c=(u-p[x])*(u-p[x])-(u.x-swp)*(u.x-swp);        if(abs(a)<eps)return u.y-c/b*v.y;        ld delta=sqrt(max((ld)0,b*b-4*a*c));        return u.y+(-b+delta)/(2*a)*v.y;    }    inline bool operator<(pr y)const    {        ld xx=get_y(swp),yy=y.get_y(swp);        if(abs(xx-yy)<eps&&x!=-1&&y.x!=-1)return p[x].x<p[y.x].x;        return xx+eps<yy;    }};struct ev{    ld T;    int x,y,z;    ev(){}    ev(ld T,int x,int y,int z):T(T),x(x),y(y),z(z){}    inline bool operator <(ev i)const{return T>i.T;}};priority_queue<ev>event;#define sqr(x)  ((x)*(x))inline void add(int x,int y,int z){    point a=p[x],b=p[y],c=p[z];    point v=c-b,w=a-b;    ld d=w^v;    if(d<eps)return;    v=point(v.y,-v.x),w=point(w.y,-w.x);    point P=(b+c)/2,Q=(a+b)/2;    ld t=(w^(Q-P))/d;    ld aa=P.x+v.x*t,bb=P.y+v.y*t;    t=aa+sqrt(sqr(aa-a.x)+sqr(bb-a.y));    event.push(ev(t,x,y,z));}inline void init(){    scanf("%d",&n);    for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);}set<pr>All;inline bool cmp(int a,int b){return p[a]<p[b];}int pos[100001];pair<int,int>ed[1000001];int edn;inline void Pre(){    for(int i=0;i<n;i++)pos[i]=i;    sort(pos,pos+n,cmp);    int i=1;    ld lst=p[pos[0]].x;    swp=lst+1;    while(i<n&&abs(p[pos[i]].x-lst)<eps)    {        All.insert(pr(pos[i-1],pos[i]));        ed[edn++]=make_pair(pos[i-1],pos[i]);        i++;    }    int s=i;    for(;i<n+1;i++)    {        while(!event.empty())        {            if((i^n)&&event.top().T>p[pos[i]].x+eps)break;            ev x=event.top();event.pop();            swp=(x.T+lst)/2;            New(tmp,All.find(pr(x.y,x.z)));            New(tmp0,tmp);            if(tmp==All.end()||tmp==All.begin()||((--tmp0)->x^x.x))continue;            New(tmp1,tmp0);            if(tmp0!=All.begin())--tmp0,add(tmp0->x,x.x,x.z);            if(++(tmp0=tmp)!=All.end())add(x.x,x.z,tmp0->y);            All.erase(tmp1,tmp0);            All.insert(pr(x.x,x.z));            ed[edn++]=make_pair(x.x,x.z);        }        if(i==n)break;        lst=swp=p[pos[i]].x,curx=p[pos[i]].y;        New(tmp,All.lower_bound(pr(-1,-1)));        if(tmp!=All.end()&&abs(tmp->get_y(swp)-curx)<eps)        {            int d=tmp->x,u=tmp->y;            New(tmp0,tmp);            if(++tmp0!=All.end())add(pos[i],u,tmp0->y);            if(tmp!=All.begin())            {                --(tmp0=tmp);                add(tmp0->x,d,pos[i]);            }            All.erase(tmp);            ed[edn++]=make_pair(d,pos[i]);            ed[edn++]=make_pair(pos[i],u);            All.insert(pr(d,pos[i]));            All.insert(pr(pos[i],u));        }        else        {            int Mid=tmp==All.end()?pos[s-1]:tmp->x;            if(tmp!=All.end())add(pos[i],Mid,tmp->y);            if(tmp!=All.begin()){New(tmp0,tmp);add((--tmp0)->x,Mid,pos[i]);}            ed[edn++]=make_pair(pos[i],Mid);            All.insert(pr(pos[i],Mid));            All.insert(pr(Mid,pos[i]));        }    }}int f[100001];#define dis(a) (sqr(p[a.x].x-p[a.y].x)+sqr(p[a.x].y-p[a.y].y))inline bool cmp2(pair<int,int> a,pair<int,int> b){return dis(a)<dis(b);}struct Chain{int u;ld len;Chain*next;}*Head[100001];inline void Add(int u,int v,ld len){Chain *tp=new Chain;tp->u=v;tp->len=len;tp->next=Head[u];Head[u]=tp;}int F[109001][17];ld Data[100001][17];int Dep[100001];ld Query(int u,int v){    int j=16;    ld res=0;    if(Dep[u]<Dep[v])swap(u,v);    while(~j)    {        if(Dep[F[u][j]]>=Dep[v])            res=max(res,Data[u][j]),u=F[u][j];        j--;    }    j=16;    while(~j)    {        if(F[u][j]^F[v][j])res=max(res,max(Data[u][j],Data[v][j])),u=F[u][j],v=F[v][j];        j--;    }    return u==v?res:max(res,max(Data[u][0],Data[v][0]));}char c;inline void read(int&a){a=0;do c=getchar();while(c<'0'||c>'9');while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}void Reply(){    int n,u,v;    read(n);    while(n--)    {        read(u),read(v);        u--,v--;        printf("%.6f\n",Query(u,v));    }}void DFS(int u){    for(int i=1;i<=16;i++)        F[u][i]=F[F[u][i-1]][i-1],    Data[u][i]=max(Data[u][i-1],Data[F[u][i-1]][i-1]);    Dep[u]=Dep[F[u][0]]+1;    for(Chain *tp=Head[u];tp;tp=tp->next)        if(tp->u^F[u][0])F[tp->u][0]=u,Data[tp->u][0]=tp->len,DFS(tp->u);    if(u==F[u][0])        Reply();}int find(int x){return x==f[x]?x:f[x]=find(f[x]);}inline void kru(){    init();    Pre();    sort(ed,ed+edn,cmp2);    for(int i=0;i<n;i++)f[i]=i;    int j=0;    for(int i=1;i<n;i++)    {        int u=ed[j].x,v=ed[j].y;        while(find(u)==find(v))        {            j++;            u=ed[j].x,v=ed[j].y;        }        f[find(u)]=find(v);        ld t;        Add(u,v,t=sqrt(dis(ed[j]))),Add(v,u,t);    }    DFS(0);}int main(){    kru();}
0 0
原创粉丝点击