#include <bits/stdc++.h>
using namespace std;
const long double INF = 1e18;
const long double EPS = 1e-12;
bool equals(long double a, long double b) { return fabs(a - b) < EPS; }
struct edge {
  int u, v;
  long long cap;
  long double cost;
  edge(int _u, int _v, long long _cap, long double _cost) {
    u = _u;
    v = _v;
    cap = _cap;
    cost = _cost;
  }
};
struct min_cost_flow {
 public:
  int n, s, t;
  long long flow;
  long double cost;
  vector<vector<int> > graph;
  vector<edge> e;
  vector<long double> dist;
  vector<int> parent;
  min_cost_flow(int _n) {
    n = _n;
    graph.assign(n, vector<int>());
  }
  void add_edge(int u, int v, long long cap, long double _cost,
                bool directed = true) {
    graph[u].push_back(e.size());
    e.push_back(edge(u, v, cap, _cost));
    graph[v].push_back(e.size());
    e.push_back(edge(v, u, 0, -_cost));
    if (!directed) {
      add_edge(v, u, cap, cost, true);
    }
  }
  pair<long long, long double> get_min_cost_flow(int _s, int _t) {
    s = _s;
    t = _t;
    flow = 0, cost = 0;
    while (SPFA()) {
      flow += send_flow(t, 1LL << 62);
    }
    return make_pair(flow, cost);
  }

 private:
  bool SPFA() {
    parent.assign(n, -1);
    dist.assign(n, INF);
    dist[s] = 0;
    vector<int> queuetime(n, 0);
    queuetime[s] = 1;
    vector<bool> inqueue(n, 0);
    inqueue[s] = true;
    queue<int> q;
    q.push(s);
    bool negativecycle = false;
    while (!q.empty() && !negativecycle) {
      int u = q.front();
      q.pop();
      inqueue[u] = false;
      for (int i = 0; i < (int)graph[u].size(); i++) {
        int eIdx = graph[u][i];
        int v = e[eIdx].v;
        long double w = e[eIdx].cost;
        long long cap = e[eIdx].cap;
        if (dist[u] + w + EPS < dist[v] && cap > 0) {
          dist[v] = dist[u] + w;
          parent[v] = eIdx;
          if (!inqueue[v]) {
            q.push(v);
            queuetime[v]++;
            inqueue[v] = true;
            if (queuetime[v] == n + 2) {
              negativecycle = true;
              break;
            }
          }
        }
      }
    }
    return !equals(dist[t], INF);
  }
  long long send_flow(int v, long long cur_flow) {
    if (parent[v] == -1) {
      return cur_flow;
    }
    int eIdx = parent[v];
    int u = e[eIdx].u;
    long double w = e[eIdx].cost;
    long long f = send_flow(u, min(cur_flow, e[eIdx].cap));
    cost += f * w;
    e[eIdx].cap -= f;
    e[eIdx ^ 1].cap += f;
    return f;
  }
};
long double dis(pair<int, int> a, pair<int, int> b) {
  int dx = a.first - b.first;
  int dy = a.second - b.second;
  return sqrt(dx * dx + dy * dy);
}
const int MAX = 1e6 + 6;
int cnt[MAX];
int n;
int main() {
  scanf("%d", &n);
  vector<pair<int, int> > v;
  int max_y = 0;
  for (int i = int(1); i < int(n + 1); i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    cnt[y + 1000]++;
    max_y = max(max_y, y + 1000);
    v.emplace_back(y, x);
  }
  sort(v.begin(), v.end(), greater<pair<int, int> >());
  if (cnt[max_y] != 1) {
    puts("-1");
    return 0;
  }
  min_cost_flow mcmf(3 * n);
  int source = 2 * n, sink = 2 * n + 1;
  for (int i = int(0); i < int(n); i++) {
    if (i) {
      mcmf.add_edge(source, i, 1, 0);
    }
    mcmf.add_edge(i + n, sink, 2, 0);
  }
  for (int i = int(1); i < int(v.size()); i++) {
    for (int j = int(0); j < int(i); j++) {
      if (v[j].first > v[i].first) {
        mcmf.add_edge(i, j + n, 1, dis(v[i], v[j]));
      }
    }
  }
  pair<long long, long double> p = mcmf.get_min_cost_flow(source, sink);
  if (p.first != n - 1) {
    puts("-1");
  } else {
    cout << fixed << setprecision(15) << p.second << endl;
  }
  return 0;
}
