#include <bits/stdc++.h>
using namespace std;
namespace MCF {
const int MAX = 810;
const double INF = (double)1e15;
struct edge {
  int from, to, flow, cap;
  double cost;
};
vector<edge> e;
vector<int> g[MAX];
double phi[MAX], dist[MAX];
priority_queue<pair<double, int> > q;
int n, s, t, p[MAX];
void init(int n_, int s_, int t_) {
  n = n_, s = s_, t = t_;
  for (int i = 0; i < n; i++) {
    g[i].clear();
    p[i] = 0;
  }
  e.clear();
}
void addEdge(int from, int to, int cap, double cost) {
  edge ed;
  ed.from = from, ed.to = to, ed.flow = 0, ed.cap = cap, ed.cost = cost;
  g[from].push_back((int)e.size());
  e.push_back(ed);
  ed.from = to, ed.to = from, ed.flow = cap, ed.cap = cap, ed.cost = -cost;
  g[to].push_back((int)e.size());
  e.push_back(ed);
}
void bellmanFord() {
  for (int i = 0; i < n; i++) dist[i] = INF;
  dist[s] = 0;
  while (1) {
    int change = 0;
    for (auto o : e) {
      int from = o.from;
      int to = o.to;
      if (o.flow == o.cap || dist[from] == INF) continue;
      if (dist[from] + o.cost < dist[to]) {
        dist[to] = dist[from] + o.cost;
        change = 1;
      }
    }
    if (!change) break;
  }
}
void dijkstra() {
  while (!q.empty()) q.pop();
  for (int i = 0; i < n; i++) {
    dist[i] = INF;
    q.push({-dist[i], i});
  }
  dist[s] = 0;
  q.push({0, s});
  while (!q.empty()) {
    int u = q.top().second;
    double ct = -q.top().first;
    q.pop();
    if (ct > dist[u]) continue;
    if (dist[u] == INF) break;
    for (int id : g[u]) {
      if (e[id].flow == e[id].cap) continue;
      int to = e[id].to;
      double w = e[id].cost;
      if (ct + w < dist[to]) {
        dist[to] = ct + w;
        p[to] = id;
        q.push({-dist[to], to});
      }
    }
  }
}
pair<double, int> maxFlowMinCost() {
  double flowCost = 0;
  int flow = 0;
  while (1) {
    dijkstra();
    if (dist[t] == INF) break;
    int push = (int)1e9;
    int u = t;
    while (u != s) {
      edge tmp = e[p[u]];
      push = min(push, tmp.cap - tmp.flow);
      u = tmp.from;
    }
    flow += push;
    u = t;
    while (u != s) {
      edge tmp = e[p[u]];
      e[p[u]].flow += push;
      e[p[u] ^ 1].flow -= push;
      flowCost += 1LL * push * tmp.cost;
      u = tmp.from;
    }
  }
  return {flowCost, flow};
}
}  // namespace MCF
int n;
struct pt {
  int x, y;
  bool operator<(const pt &p) const { return y > p.y; }
} a[405];
double dist(pt a, pt b) {
  return sqrt(0.0 + (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main() {
  scanf("%d", &n);
  MCF::init(2 * n + 2, 0, 2 * n + 1);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &a[i].x, &a[i].y);
    MCF::addEdge(0, i, 2, 0);
    MCF::addEdge(i + n, 2 * n + 1, 1, 0);
  }
  sort(a + 1, a + n + 1);
  if (a[1].y == a[2].y) {
    printf("-1\n");
    return 0;
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 2; j <= n; j++) {
      if (a[i].y <= a[j].y) continue;
      MCF::addEdge(i, j + n, 1, dist(a[i], a[j]));
    }
  }
  pair<double, int> r = MCF::maxFlowMinCost();
  if (r.second == n - 1)
    printf("%.7lf\n", r.first);
  else
    printf("-1\n");
  return 0;
}
