Originally this algorithm in the author computer has been neglected for some time, but today just do HDU 1007 See this problem, today to share the code out!
We first sort all the points in coordinates x, and then make a line L as "split line", so that we can recursively.
We can then divide the points into the left and right halves according to the coordinates of the x-axis. Then the shortest distance must be in the left half, the right half, and one of the point pairs that crosses about.
Then you may have a question: the most recent point pair must also be in these three areas, this is not the equivalent of nothing?
It's not really. We can assume that by recursion the minimum distance to the left is D1, the right minimum distance is D2, so δ= min (d1,d2)
, if the point pair across the left and right may be the shortest distance, then it must be smaller than δ. In the area with the center of L and the maximum distance of 2δ, there is a maximum of O (n) rectangles. In addition, it can be proved that for each rectangular region, the maximum number of attempts to 8 points will be able to find the shortest distance (the introduction of the algorithm in section 33.4 has detailed proof, here no longer repeat).
Thus, we can write a recursive: t (n) =2t (N/2) +o (n), which can be solved by the Master method with the time complexity T (n) =o (NLOGN). Plus the sort time O (NLOGN), so the entire algorithm runs for T (n) ' = t (n) +o (NLOGN) = O (Nlogn).
Below, with this algorithm, we can write a code to:
/** * find closest distance in n points. * time cost: o (NLOGN) * Author: Zheng Chen / Arclabs001 * Copyright 2015 Xi ' An university of posts & telecommunications *//** * algorithm: * first of all, sort the points in ascending order by x. * Divide the array into 2 parts, and find the Smallest distance within two parts. * let min as the smaller one, and find the smallest split distance. */#include < iostream> #include <algorithm> #include <cmath> #define inf 0x6fffffffusing namespace std;struct Node{double x, y;friend bool operator < (const node &A,&NBSP;CONST&NBSP;NODE&NBSP;&B) {if (a.x == b.x) Return a.y < b.y;return a.x < b.x;}}; node* point = null;/** * calculate the distance between two points. * @return [double, the distance between a and b] */double _distance (const node a, const node b) {return sqrt ( a.x-b.x) * (a.x-b.x) + (A.Y-B.Y) * (A.Y-B.Y));} Double smaller (double p, double q) {return (p > q) ? q : p;} /** * [find the closest distance, divide & conquer] * @ param left [search from where] * @param right [to where] * @return [double, the smallest distance in the whole&nbsP;set of points] */double closest_distance (int left, int right) {double d = inf;double distance_tmp;if (left == right) return 0;if (right == left+1) return _distance ( Point[left], Point[right] );int mid = (left + right) / 2;d = smaller ( closest_distance (left,mid) , Closest_ Distance (mid,right) ); for (int i=mid-1; i>=left && point[mid].x - point[i].x < d; i--) {for (int j = mid+1; j<=right & & point[j].x - point[mid].x < d && fabs ( Point[i].y &NBSP;-&NBSP;POINT[J].Y) ( < d; j++) {distance_tmp = _distance ( Point[i], point[j] ); if (distance_tmp < d) d = distance_tmp;}} Return d;} Int main () { int n; cin>>n; point = new node[n]; for (int i=0; i<n ; i++) { cin>>point[i].x> >point[i].y; } sort (point,point+n); Cout<<closest_distance (0,n-1) <<endl; return 0;}
Of course, applying this code directly to HDOJ will cause exceed time Limit, you know ^_^
Beginner algorithm-Divide and conquer the nearest point pair on plane (Closest pair)-hdu 1007