1 /*
2 * 题目要求:求最近点对(一个点在station内,一个点在agent内)
3 */
4
5 #include <cmath>
6 #include <cstdio>
7 #include <cstdlib>
8 #include <iostream>
9 #include <algorithm>
10
11 using namespace std;
12
13 const int N = 200005;
14 const double INF = 1e20;
15
16 struct point {
17 int f;
18 double x;
19 double y;
20 }p[N];
21 int tmp[N];
22
23 double dis(point A, point B) {
24 return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
25 }
26
27 int cmp(const point &a, const point &b) {
28 if (a.x != b.x) return a.x < b.x;
29 return a.y < b.y;
30 }
31
32 int cmp1(const int &a, const int &b) {
33 return p[a].y < p[b].y;
34 }
35
36 double min(double a, double b) {
37 return a > b ? b : a;
38 }
39
40 double closestPair(int left, int right) {
41 double d = INF;
42 if (left == right) return d; //同属station点,返回无穷大
43 if (left+1 == right) return d; //同属agent点,返回无穷大
44 int mid = (left + right) >> 1;
45 double d1 = closestPair(left, mid);
46 double d2 = closestPair(mid+1, right);
47 d = min(d1, d2);
48 int k = 0;
49 for (int i=left; i<=right; ++i) {
50 if (fabs(p[mid].x- p[i].x) <= d) tmp[k++] = i;
51 }
52 sort(tmp, tmp+k, cmp1);
53 for (int i=0; i<k; ++i) {//只有当一个点为station的点,另一个点为agent点时,才计算两点距离
54 for (int j=i+1; j<k && p[tmp[j]].y-p[tmp[i]].y<d && ((p[tmp[j]].f==0&&p[tmp[i]].f==1)||(p[tmp[j]].f==1&&p[tmp[i]].f==0)); ++j) {
55 double d3 = dis(p[tmp[i]], p[tmp[j]]);
56 if (d3 < d) d = d3;
57 }
58 }
59 return d;
60 }
61
62 int main() {
63 int n, t;
64 scanf ("%d", &t);
65 while (t--) {
66 scanf ("%d", &n);
67 for (int i=0; i<n; ++i) {
68 scanf ("%lf%lf", &p[i].x, &p[i].y);
69 p[i].f = 0; //标志为station的点
70 }
71 for (int i=n; i<n+n; ++i) {
72 scanf ("%lf%lf", &p[i].x, &p[i].y);
73 p[i].f = 1; //标志为agent的点
74 }
75 if (n == 1) printf ("%.lf\n", dis(p[0], p[1]));//只有两个点,直接算
76 else {
77 sort(p, p+n+n, cmp);
78 double ans = closestPair(0, n+n-1);
79 printf ("%.3lf\n", ans);
80 }
81 }
82 return 0;
83 }