Test instructions
There are n points on the plane, and now divide them into K-sets, so that each point in each set has at least one point in the set that is between the points of Manhattan and less than x, the smallest x.
Analysis:
Converts to the K-large edge of the smallest spanning tree that evaluates to n points to generate a complete graph. Then there are a few points.
1) According to the MO team algorithm, since Benquan is the point of the Manhattan distance, each point only needs to be connected to the nearest point in each direction in the surrounding 8 directions, so that the calculated figure is the same as the smallest spanning tree calculated with the full graph, and the edges involved are greatly reduced.
2) using a tree-like array to maintain the nearest point of the Y-right 45 degrees, each point with y-x position, y+x value into the tree array, because each time the query interval (pos,last), so the tree array c[i] coverage to be changed to A[i,i+1,... A+2^k-1], K is the number of I binary end 0. There are also changes to queries and updates.
3) to the minimum spanning tree a conjecture: set a graph of the minimum spanning tree of each side of the right from small to large order of a1,a2....an-1, the graph of any spanning tree to the right of each edge from small to large order of B1,B2,.. Bn-1, then Ai<=bi (i=1,2,... n-1).
Code:
POJ 3241//sep9#include <iostream> #include <algorithm>const int maxn=10024;using namespace Std;int n,k,e; struct P{int x,y,ids;} P[maxn];struct edge{int u,v,w;} Edge[maxn*4];int c[4000],d[4000],fa[maxn];int lowbit (int x) {return x& (x^ (x-1));} int cmp_p (P a,p b) {if (a.x!=b.x) return A.x<b.x;return a.y<b.y;} int cmp_e (EDGE A,edge b) {return A.W<B.W;} void query (int ids,int pos,int val) {pos+=1000;int t_ids=-1,ret=int_max;for (int i=pos;i<4000;i+=lowbit (i)) if (ret >c[i]) {ret=c[i];t_ids=d[i];} if (t_ids!=-1) {edge[e].u=ids;edge[e].v=t_ids;edge[e++].w=ret-val;}} void update (int ids,int pos,int val) {pos+=1000;for (int i=pos;i;i-=lowbit (i)) if (Val<c[i]) {c[i]=val;d[i]=ids;}} void Deal () {memset (c,63,sizeof (c)); sort (p,p+n,cmp_p); for (int i=n-1;i>=0;--i) {int Pos=p[i].y-p[i].x;int val=p[i] . Y+p[i].x;query (p[i].ids,pos,val); update (p[i].ids,pos,val);}} int find (int x) {return x==fa[x]?x:fa[x]=find (fa[x]);} int solve () {if (n==k) return 0;e=0;deal (); for (int i=0;i<n;++i) swap (p[i].x,p[i].y);d EAL (), for (int i=0;i<n;++i) p[i].y=-p[i].y;deal (), for (int i=0;i<n;++i) swap (P[I].X,P[I].Y);d EAL (), for (int i =0;i<n;++i) Fa[i]=i;sort (edge,edge+e,cmp_e); for (int i=0;i<e;++i) {int pa=find (EDGE[I].U); int Pb=find (Edge[i]. v); if (PA!=PB) {fa[pa]=pb;n--;if (n==k) return EDGE[I].W;}}} int main () {scanf ("%d%d", &n,&k), for (int i=0;i<n;++i) {scanf ("%d%d", &p[i].x,&p[i].y);p [I].ids=i;} printf ("%d", solve ());}
POJ 3241 Object Clustering manhattan smallest spanning tree