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
- BZOJ3911: SGU383 Caravans
- ural 2034. Caravans
- URAL 2034 Caravans (最短路 + 二分)
- 【算法设计与数据结构】二分法解决最大值最小化问题—进阶篇— URAL 2034 Caravans
- Java自动内存管理机制(二) 运行时数据区
- android中获取view的位置
- TCP/IP四层模型
- VS中Dubug和Release版本下的一些区别
- nncq---7月15日 修改(错误的话新添加一个对话框)
- BZOJ3911: SGU383 Caravans
- HTML5本地存储之Web Storage篇
- hdu1006
- Android sepolicy规则
- 16.7.25
- 三角形继续升级
- IOS开发 GIT更新fork出来的代码
- JNI(Java Native Interface)首次使用
- LLDB之基本命令使用(Swift)