//
// Created by lenovo on 2023/8/12.
//
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
const int MAXN = 1000, INF = 0x3f3f3f3f; //定义一个INF表示无穷大。
int n; //图的边数
double g[MAXN][MAXN], dist[MAXN], res;
//我们用g[][]数组存储这个图,dist[]储存到集合S的距离,res保存结果。
bool book[MAXN];//用book数组记录某个点是否加入到集合S中。
double getlen(double x1, double x2, double y1, double y2) {
return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}
void prim() {
dist[1] = 0;
book[1] = true;
for (int i = 2; i <= n; i++) // dist[i]在最开始的时候是最大值INF
dist[i] = min(dist[i], g[1][i]);
for (int i = 2; i <= n; i++) {
double tmp = INF;
int t = -1;
for (int j = 2; j <= n; j++) {
if (!book[j] && dist[j] < tmp) {
tmp = dist[j];
t = j;
}
}
if (t == -1) {
res = INF;
return;
}
book[t] = true;
res += dist[t];
for (int j = 2; j <= n; j++)
dist[j] = min(dist[j], g[t][j]);
}
}
int main() {
// 边的数目
while (cin >> n) {
vector<pair<double, double>> pos(n);
for (int i = 0; i < n; i++)
cin >> pos[i].first >> pos[i].second;
for (int i = 1 ; i <= n ; i++) {
for (int j = 1; j <= n ; j++) {
g[i][j] = INF;//初始化任意两个点之间的距离为正无穷(表示这两个点之间没有边)
}
dist[i] = INF;//初始化所有点到集合S的距离都是正无穷
}
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
double distance = getlen(pos[i].first, pos[j].first, pos[i].second,
pos[j].second);
g[i + 1][j + 1] = g[j + 1][i + 1] = distance;
}
}
prim();
printf("%.2f\n", res);
}
}
// 64 位输出请用 printf("%lld")
// 64 位输出请用 printf("%lld")