题意:给出$N$个点,求其中周长最小的三角形(共线的也计算在内)。$N \leq 2 \times 10^5$
这道题唤起了我对平面最近点对的依稀记忆
考虑平面最近点对的分治,将分界线两边的求解改为求三角形的最小边长即可。
小心坐标乘积爆int
不难但就是想不出
1 //This code is written by Itst
2 #include<bits/stdc++.h>
3 #define int long long
4 #define ld long double
5 #define eps (ld)1e-10
6 using namespace std;
7
8 inline int read(){
9 int a = 0;
10 bool f = 0;
11 char c = getchar();
12 while(c != EOF && !isdigit(c)){
13 if(c == '-')
14 f = 1;
15 c = getchar();
16 }
17 while(c != EOF && isdigit(c)){
18 a = (a << 3) + (a << 1) + (c ^ '0');
19 c = getchar();
20 }
21 return f ? -a : a;
22 }
23
24 const int MAXN = 200010;
25 struct node{
26 int x , y;
27 }now[MAXN] , pot[MAXN];
28 int N;
29
30 ld dis(node a , node b){
31 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
32 }
33
34 ld len(node a , node b , node c){
35 return dis(a , b) + dis(b , c) + dis(a , c);
36 }
37
38 bool cmp1(node a , node b){
39 return a.y < b.y;
40 }
41
42 ld solve(int l , int r){
43 if(r - l <= 4){
44 ld minN = 0x3f3f3f3f;
45 for(int i = l ; i <= r ; i++)
46 for(int j = i + 1 ; j <= r ; j++)
47 for(int k = j + 1 ; k <= r ; k++)
48 minN = min(minN , len(now[i] , now[j] , now[k]));
49 return minN;
50 }
51 int mid = l + r >> 1;
52 ld k = (now[mid].x + now[mid + 1].x) * (ld)0.5 , d1 = solve(l , mid) , d2 = solve(mid + 1 , r) , d = min(d1 , d2);
53 sort(now + l , now + r + 1 , cmp1);
54 int p = 0;
55 for(int i = l ; i <= r ; i++)
56 if(fabs(now[i].x - k) + eps < d)
57 pot[++p] = now[i];
58 for(int i = 1 ; i <= p ; i++)
59 for(int j = i + 1 ; j <= p && pot[j].y - pot[i].y + eps < d ; j++)
60 for(int k = j + 1 ; k <= p && pot[k].y - pot[i].y + eps < d ; k++)
61 d = min(d , len(pot[i] , pot[j] , pot[k]));
62 return d;
63 }
64
65 bool cmp(node a , node b){
66 return a.x < b.x;
67 }
68
69 signed main(){
70 #ifdef LG
71 freopen("4423.in" , "r" , stdin);
72 //freopen("4423.out" , "w" , stdout);
73 #endif
74 N = read();
75 for(int i = 1 ; i <= N ; i++){
76 now[i].x = read();
77 now[i].y = read();
78 }
79 sort(now + 1 , now + N + 1 , cmp);
80 cout << fixed << setprecision(6) << solve(1 , N);
81 return 0;
82 }