#include<cstdio>
#include<vector>
#include<algorithm>
#include<math.h>
#include<iostream>
#define N 101
using namespace std;
float  res;
struct point {//定义点集
    float x;
    float y;
};
struct G { //图,起点终点 ,距离
    int from;
    int to;
    float weight;
};

vector<point> vec;
vector<G> graph;
//并查集,在合并的时候求距离
int father[N];
int height[N];
float distance(point lhs, point rhs) {//算两点之间距离之和
    return pow(pow((lhs.x - rhs.x), 2) + pow((lhs.y - rhs.y), 2), 0.5);
}
void Init(int n) {//初始化并查集和两个集合
    for (int ic = 0 ; ic < n; ++ic) {
        father[ic] = ic ;
        height[ic] = 0;
    }
    graph.clear();
    vec.clear();
    res = 0;
}
int Find(int x) {//查
    if (x != father[x]) {
        return Find(father[x]);
    } else {
        return father[x];
    }
}
void Union(int x, int y, float weight) {//并
    x = Find(x);
    y = Find(y);
    if (x == y) {
        res = res;
    } else {
        res += weight;
        if (height[x] > height[y]) {
            father[y] = x;
        } else if (height[y] > height[x]) {
            father[x] = y;
        } else {
            father[x] = y;
            ++ height[y] ;
        }
    }
}
bool comp(G lhs, G rhs) {//按权值从小到大排列
    if (lhs.weight < rhs.weight) {
        return  true;
    } else {
        return false;
    }
}
int main() {
    int n;
    point p;
    G g;
    scanf("%d", &n);
    Init(n);
    for (int iw = 0 ; iw < n ; ++iw) {
        cin >> p.x >> p.y; //传入点
        vec.push_back(p);
    }
    for (int ix = 0 ; ix < n - 1 ; ++ix) {
        for (int j = ix + 1 ; j < n ; ++j) {
            g.from = ix;
            g.to = j;
            g.weight = distance(vec[ix], vec[j]);
            graph.push_back(g);
        }
    }
    sort(graph.begin(), graph.end(), comp);
    for (int idx = 0 ; idx < graph.size() ; ++idx) {
        Union(graph[idx].from, graph[idx].to, graph[idx].weight);
    }
    printf("%.2f\n", res);
}