#include <bits/stdc++.h>
using namespace std;
const double oo = 1e9;
int x[405], y[405], n;
struct Edge {
  int u, v, cap, flow;
  double cost, _cost;
};
struct MinCostFlow {
  void init(int N, int s, int t) {
    this->N = N;
    this->s = s;
    this->t = t;
  }
  void addEdge(int u, int v, int cap, double cost) {
    Edge e1 = {u, v, cap, 0, cost, cost};
    Edge e2 = {v, u, 0, 0, -cost, -cost};
    adj[u].push_back(int(E.size()));
    E.push_back(e1);
    adj[v].push_back(int(E.size()));
    E.push_back(e2);
  }
  bool dijkstra() {
    for (int i = 0; i < N; i++) {
      D[i] = oo;
      tr[i] = -1;
    }
    D[s] = 0;
    set<pair<double, int> > se;
    se.insert(pair<double, int>(0, s));
    while (!se.empty()) {
      pair<double, int> u = *se.begin();
      se.erase(se.begin());
      for (int i = 0; i < int(adj[u.second].size()); i++) {
        int id = adj[u.second][i];
        if (E[id].cap == E[id].flow) continue;
        int v = E[id].v;
        double cost = D[u.second] + E[id].cost;
        if (cost < D[v]) {
          tr[v] = id;
          set<pair<double, int> >::iterator it =
              se.find(pair<double, int>(D[v], v));
          if (it != se.end()) se.erase(it);
          D[v] = cost;
          se.insert(pair<double, int>(D[v], v));
        }
      }
    }
    return D[t] < oo;
  }
  vector<int> findPath() {
    vector<int> res;
    int u = t;
    while (tr[u] != -1) {
      int id = tr[u];
      res.push_back(id);
      u = E[id].u;
    }
    return res;
  }
  void augmentPath(vector<int>& P) {
    int minFlow = oo;
    for (int i = 0; i < int(P.size()); i++) {
      int id = P[i];
      int flow = E[id].cap - E[id].flow;
      minFlow = min(minFlow, flow);
    }
    for (int i = 0; i < int(P.size()); i++) {
      int id = P[i];
      E[id].flow += minFlow;
      E[id ^ 1].flow -= minFlow;
      E[id ^ 1].cost = 0;
    }
  }
  pair<double, int> minCostFlow() {
    while (dijkstra()) {
      vector<int> P = findPath();
      for (int i = 0; i < int(E.size()); i++) {
        if (E[i].flow == E[i].cap) continue;
        E[i].cost += D[E[i].u] - D[E[i].v];
      }
      augmentPath(P);
    }
    pair<double, int> res(0, 0);
    for (int i = 0; i < int(E.size()); i++) {
      if (E[i]._cost > 0) {
        res.first += E[i].flow * E[i]._cost;
      }
      if (E[i].u == 0) {
        res.second += E[i].flow;
      }
    }
    return res;
  }
  int N, s, t;
  int tr[1005];
  double D[1005];
  vector<int> adj[1005];
  vector<Edge> E;
};
double getDistance(int x0, int y0, int x1, int y1) {
  return sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
}
void solve() {
  MinCostFlow mcf;
  mcf.init(2 * n + 2, 0, 2 * n + 1);
  for (int i = 1; i <= n; i++) {
    mcf.addEdge(0, i, 2, 0);
    mcf.addEdge(n + i, 2 * n + 1, 1, 0);
    for (int j = 1; j <= n; j++) {
      if (i == j || y[j] >= y[i]) continue;
      mcf.addEdge(i, j + n, 1, getDistance(x[i], y[i], x[j], y[j]));
    }
  }
  pair<double, int> res = mcf.minCostFlow();
  if (res.second != n - 1) {
    cout << "-1\n";
    return;
  }
  cout << fixed << setprecision(9) << res.first << "\n";
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n;
  for (int i = 1; i <= n; i++) cin >> x[i] >> y[i];
  solve();
  return 0;
}
