Test instructions: Conversion is the first n-k edge of Manhattan's smallest spanning tree
Reference: Mo Tao's paper "The smallest spanning tree in Manhattan"
/*problem:3241 user:96655memory:920k time:94mslanguage:c++ result:accepted*/#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cstdlib>#include<cmath>using namespaceStd;typedefLong LongLL;Const intmaxn=10005;Const intinf=0x3f3f3f3f;Const intmaxm=4015;intn,k,p;structpoint{intX,y,id; BOOL operator< (ConstPoint &e)Const { if(x==e.x)returny<e.y; returnx<e.x; }} POINT[MAXN];structedge{intu,v,w; BOOL operator< (ConstEdge &e)Const { returnw<E.W; }} EDGE[MAXN*Ten];voidAddedge (intAintBintLintR) { ++p; EDGE[P].U=A; EDGE[P].V=b; EDGE[P].W=abs (lr);}structnode{intLen,id;} node[(MAXM+Ten) <<2];voidPushup (intRT) {Node[rt].len=min (node[rt*2].len,node[rt*2+1].len); if(node[rt].len==node[rt*2].len) node[rt].id=node[rt*2].id; Elsenode[rt].id=node[rt*2+1].id;}voidChangeintRtintLintr,point TT) { if(l==r) {Node[rt].len=tt.x+Tt.y; Node[rt].id=tt.id; return; } intpos=tt.y-tt.x+1005; intM= (l+r) >>1; if(pos<=m) Change (rt*2, L,M,TT); ElseChange (rt*2+1, m+1, R,TT); Pushup (RT);} Node Query (intRtintLintRintXinty) { if(x<=l&&r<=y)returnNode[rt]; intM= (l+r) >>1; if(y<=m)returnQuery (rt*2, L,m,x,y); Else if(x>m)returnQuery (rt*2+1, m+1, R,x,y); Else{Node t1,t2; T1=query (rt*2, L,m,x,y); T2=query (rt*2+1, m+1, R,x,y); if(T1.len<t2.len)returnT1; Else returnT2; }}intFA[MAXN];intFindintx) { if(X==fa[x])returnx; returnfa[x]=find (Fa[x]);}voidinit () { for(intI=0; i< (maxm<<2); ++i) Node[i].len=inf,node[i].id=-1;}voidbuild () {sort ( point+1, point+1+N); Init (); for(intI=n; I>0; --i) {ints=point[i].x+point[i].y; Node T=query (1,1, maxm,point[i].y-point[i].x+1005, MAXM); if(t.id!=-1) Addedge (Point[i].id,t.id,s,t.len); Change (1,1, Maxm,point[i]); }}intsolve () {Sort (Edge+1, edge+p+1); intCnt=0; for(intI=1; i<=p; ++i) {intfx=find (EDGE[I].U); intfy=find (EDGE[I].V); if(fx!=FY) {Fa[fy]=FX; ++CNT; if(cnt==n-k)returnEDGE[I].W; } }}intMain () {scanf ("%d%d",&n,&k); for(intI=1; i<=n; ++i) scanf ("%d%d", &point[i].x,&point[i].y), point[i].id=i; for(intI=1; i<=n; ++i) fa[i]=i; P=0; Build (); for(intI=1; i<=n; ++i) point[i].y=-point[i].y; Build (); for(intI=1; i<=n; ++i) point[i].y=-Point[i].y,swap (POINT[I].X,POINT[I].Y); Build (); for(intI=1; i<=n; ++i) point[i].y=-point[i].y; Build (); printf ("%d\n", Solve ()); return 0;}View Code
POJ3241 Object Clustering Manhattan minimum spanning tree