Description
Input
Output
The scanning line is used to find the dual graph of the plane graph and then the minimum spanning tree is obtained, and the combination is combined by rank to query the maximum weight of the path between two points.
#include <stdio.h>#include<algorithm>#include<vector>#include<Set>#include<cmath>intf[200007],f2[200007],h2[200007];int Get(int*f,intx) { intA=X,c; while(X!=f[x]) x=F[x]; while(X!=f[a]) c=f[a],f[a]=x,a=C; returnx;}intGet2 (intx) { while(X!=f2[x]) x=F2[x]; returnx;}voidMergeintAintb) {a=Get(f,a); b=Get(F,B); if(a<b) f[b]=A; Elsef[a]=b;}DoubleX;structln{DoubleK,b;intID; Double operator()(DoubleXConst{returnk*x+b;} BOOL operator< (ln W)Const{return operator() (X) +1e-8<W (X);}}; STD::Set<ln>Line ;structpos{Doublex, y; voidR () {scanf ("%LF%LF",&x,&y); }}ps[100007],qs[100007][2];structdir{DoubleD; intI1,i2; BOOL operator< (dir W)Const{returnd<w.d;}}; Std::vector<dir>vs[100007];structev{intT; Doublex; intW; BOOL operator< (EV a)Const{returnx!=a.x?x<a.x:t<A.T;}} e[500007];intep=0, ee[200007];intn,m,q;structedge{intA,b,c,id; ln l; voidRintI) {ID=h; scanf ("%d%d%d",&a,&b,&c); if(ps[a].x>ps[b].x) Std::swap (A, b); if(ps[a].x!=ps[b].x) {E[ep++]= (EV) {1, ps[a].x,i}; E[ep++]= (EV) {0, ps[b].x,i}; Doublek= (PS[B].Y-PS[A].Y)/(ps[b].x-ps[a].x); L= (LN) {k,ps[a].y-ps[a].x*K,i}; } vs[a].push_back (dir) {atan2 (ps[b].y-ps[a].y,ps[b].x-ps[a].x), i,i+m}); Vs[b].push_back (dir) {atan2 (ps[a].y-ps[b].y,ps[a].x-ps[b].x), i+m,i}); } BOOL operator< (ConstEDGE&W)Const{returnc<w.c;}} es[100007];intws[100007][2];voidMAXS (int&a,intb) {if(a<b) a=b;}intMain () {scanf ("%d%d",&n,&m); for(intI=1; i<=m*2; ++i) f[i]=f2[i]=i; for(intI=1; i<=n;++i) ps[i]. R (); for(intI=1; i<=m;++i) es[i]. R (i); scanf ("%d",&q); for(intI=1; i<=q;++i) {qs[i][0]. R (); qs[i][1]. R (); E[ep++]= (EV) {2, qs[i][0].x,i}; E[ep++]= (EV) {3, qs[i][1].x,i}; } std::sort (E,e+EP); e[ep].x=e[ep-1].x+10000; Doublex0=e[0].x-10000, X1; for(intI=0, j=0;i<EP;) {x1=e[i].x; for(; j<ep&&e[j].x==x1;++j); X= (x0+x1)/2.; for(; i<j&&e[i].t==0;++i) {std::Set<ln>::iterator it=Line.find (ES[E[I].W].L); Line.erase (IT); } X= (x1+e[j].x)/2.; for(intk=i;k<j&&e[k].t==1;++k) {LN W=ES[E[K].W].L; Line.insert (w); } for(; i<j&&e[i].t==1;++i) {LN W=ES[E[I].W].L; STD::Set<ln>::iterator it=Line.find (W); ++it; if(It==line.end ()) Merge (0, e[i].w+m); ElseMerge (e[i].w+m,it->ID); --it; if(It==line.begin ()) Merge (0, E[I].W); Else--it,merge (e[i].w,it->id+m); } X=X1; for(; i<j;++i) {LN W= (LN) {0, qs[e[i].w][e[i].t-2].Y,0}; STD::Set<ln>::iterator it=Line.lower_bound (W); if(It!=line.end ()) ws[e[i].w][e[i].t-2]=it->ID; } x0=X1; } for(intI=1; i<=n;++i)if(!Vs[i].empty ()) {Std::sort (Vs[i].begin (), Vs[i].end ()); Vs[i].push_back (vs[i][0]); for(intj=1; J<vs[i].size (); + +j) {Merge (Vs[i][j-1].i2,vs[i][j].i1); }} std::sort (es+1, es+m+1); for(intI=1; i<=m;++i) { intX=get2 (Get(f,es[i].id)); intY=get2 (Get(f,es[i].id+m)); if(x&&y&&x!=y) { if(H2[x]es[i].c; Else{ if(H2[x]==h2[y]) + +H2[x]; F2[y]=x;ee[y]=es[i].c; } } } for(intI=1; i<=q;++i) { intx=Get(f,ws[i][0]), y=Get(f,ws[i][1]); if(!x| |! Y) puts ("-1"); Else{ intv=0; while(x!=y) { if(h2[x]>H2[y]) std::swap (x, y); Maxs (V,ee[x]); X=F2[x]; } printf ("%d\n", V); } } return 0;}
bzoj3051: [wc2013] Floor plan