POJ 3241 Object Clustering algorithm, Manhattan smallest spanning tree

Source: Internet
Author: User
Tags abs

Object Clustering

Time Limit: 2000MS Memory Limit: 131072K
Total Submissions: 1732 Accepted: 432

Description

We have N (n≤10000) objects, and wish to classify them into several groups by judgement of their resemblance. To simply the model with each object having 2 indexes A and B (A, b≤500). The resemblance of Object I and object j is defined by Dij = |ai-aj| + |bi-bj|, and then we say I am dij resemble to J. Now we want to find the minimum value of X, so then we can classify the N objects into K (K < N) groups, and by each GR OUP, one object is at a resemble to another object with the same group, i.e, for every object I, if I are not the only m Ember of the group, then there exists one object J (i≠j) in the same group that satisfies dij≤x

Input

The first line contains the integers N and K. The following N lines each contain, integers a and B, which describe a object.

Output

A single line contains the minimum X.

Sample Input

6 2
1 2
2 3
2 2
3 4
4 3
3 1

Sample Output

2

Source POJ monthly--2007.08.05, Li, Haoyuan ready-made things, do not write their own.

Reprint please indicate the source, thank you http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove There are some points in the two-dimensional plane, the distance between two points is Manhattan distance, and the minimum spanning tree is obtained. Simple n points, can only be done O (n^3) or O (n^2 lgn). But the MST for this Manhattan distance. One of the properties is that for a certain point, the area centered on him is divided into 8 quadrants, and for each quadrant, only the nearest point-edge is taken. In this case, because the edge is bidirectional, so for each point only need to consider 4 directions, the number of edges is O (4*n), and then use Kruskal can do O (NLGN). As for the proof:

This conclusion can be proved as follows: Suppose we build a system with point A as the origin, considering any two points B (x1,y1) and C (X2,y2) in the 45-degree area to the right of the y-axis, it is advisable to set | ab|≤| ac| (the distance here is Manhattan distance), as shown below:

| ab|=x1+y1,| ac|=x2+y2,| bc|=|x1-x2|+|y1-y2|. And because B and C are in the Y axis 45 degrees to the right of the area, there are y-x>0 and x>0. Here we discuss the situation:

1. X1>x2 and Y1>y2. this with | ab|≤| ac| contradiction;

2. X1≤x2 and Y1>y2. At this time | bc|=x2-x1+y1-y2,| ac|-| Bc|=x2+y2-x2+x1-y1+y2=x1-y1+2*y2. The various relationships in front can be y1>y2>x2>x1. hypothesis | ac|<| Bc| is y1>2*y2+x1, then | ab|=x1+y1>2*x1+2*y2,| ac|=x2+y2<2*y2<| Ab| and the premise contradiction, therefore | ac|≥| bc|;

3. X1>x2 and Y1≤y2. In the same vein as 2;

4. X1≤x2 and Y1≤y2. At this time obviously have | ab|+| bc|=| Ac|, that is | ac|>| bc|.

Comprehensive | ac|≥| Bc|, that is, in this area just select the nearest point to a edge of a. Turn from: http://blog.csdn.net/huzecong/article/details/8576908 So if you have a conclusion, how to filter out the nearest point of each region is first 8 directions, because of the bidirectional nature of the edges, We only need to consider 4 directions for one point. These 4 directions (for example, to the right of the y-axis) can be transformed into an area by coordinates (e.g. y>x). About Y=x or y=0 symmetry can be achieved. For y>x This area, if there is a point B (x1,y1) in this area for point A (x0,y0). So x1>x0&&y1-x1>y0-x0. Dist (A, B) =x1-x0+y1-y0=x1+y1-(X0+Y0), then for Point A, is to find the x1+y1 smallest point within the region. So what kind of points satisfied in this area, (x1>x0&&y1-x1>y0-x0) is the condition we will coordinate by x sort, will y-x discretization, with bit to maintain, query for a certain X0, query than (y0-x0) large x1+ Y1 the smallest point. Adding this edge, repeating 4 areas, is Kruskal.


My method: The principle is used above.

When implemented, it is also the area of computing y>x. But the tree array is sorted by the results of X-y discretization.

Because y ' x ' > Y-x

So x ' Y ' < xy

In fact, the tree-like array can not only implement the prefix and, can also implement suffixes and, there is no need to reverse. But I'm just used to it.


#include <iostream> #include <cstring> #include <cstdio> #include <math.h> #include <
Algorithm> #include <vector> using namespace std;
#define MAXN 10007 #define INF 100000000 #define MAXM int POS[MAXM],TREE[MAXM];
            void Add (int p,int val,int ID) {while (P < MAXM) {if (Val < tree[p]) {tree[p] = val;
        POS[P] = ID;
    } p + = p& (-p);
    }} int query (int p) {int id=-1,val=inf;
            while (P > 0) {if (Tree[p] < val) {val = tree[p];
        id = pos[p];
    } P-= p& (-p);
} return ID;
} struct node{int x,y,id,xsy;};
    int comp (Node A,node b) {if (a.x = = b.x) return a.y > B.y;
return a.x > b.x;
    } int Compxsy (Node A,node b) {return a.xsy < b.xsy;} struct edge{int u,v,w;
    Edge (int _u=0,int _v=0,int _w=0) {u =_u,v=_v,w=_w;
}
};
Vector<edge> Edge;
Node POINT[MAXN];
Node P[MAXN]; int dist (Node a,node b{return abs (a.x-b.x) +abs (A.Y-B.Y),} void Manhaton (int n) {for (int i = 0;i < n; i++) Point[i].xsy = P
    OINT[I].X-POINT[I].Y;
    Sort (point,point+n,compxsy);
    int cnt = 1,f=-inf;
            for (int i = 0;i < n; i++) {if (point[i].xsy! = f) {cnt++;
        f = point[i].xsy;
    } point[i].xsy = cnt;

    } sort (Point,point+n,comp);
    for (int i = 0;i < MAXM; i++) tree[i] = Inf,pos[i]=-1;
        for (int i = 0;i < n; i++) {int u = point[i].id;
        int v = query (point[i].xsy);
        if (v! =-1) edge.push_back (Edge (U,v,dist (P[U],P[V)));
    Add (Point[i].xsy,point[i].x+point[i].y,u);
    }} void Buildedge (int n) {edge.clear ();
        for (int j = 0;j < 4; j + +) {for (int i = 0;i < n; i++) point[i] = P[i];
            for (int i = 0;i < n; i++) {if (j = = 1) swap (POINT[I].X,POINT[I].Y);
    else if (j = = 2) point[i].y =-POINT[I].Y;        else if (j==3) {swap (POINT[I].X,POINT[I].Y);
            Point[i].y =-POINT[I].Y;
    }} Manhaton (n);
}} int PRE[MAXN];
    int find (int u) {if (U = = pre[u]) return u;
return Pre[u] = find (Pre[u]); } int Compedge (Edge A,edge b) {return A.W < B.W;} int MST (int n,int k) {for (int i = 0;i < n; i++) p
    Re[i] = i;
    Sort (Edge.begin (), Edge.end (), Compedge);
    int d = 0;
        for (int i = 0;i < Edge.size (); i++) {if (n = = k) return D;
        D = EDGE[I].W;
        int f1 = find (EDGE[I].U);
        int F2 = find (EDGE[I].V);
        if (f1 = = F2) continue;
        PRE[F1] = F2;
    n--;
} return D;
    } int main () {int n,k; while (scanf ("%d%d", &n,&k)!=eof) {for (int i = 0;i < n; i++) {scanf ("%d%d", &p[i].x,&p
            [I].Y];
        P[i].id = i;
        } buildedge (n);
    printf ("%d\n", MST (n,k));
} return 0;

















 }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.