#include <bits/stdc++.h>
using namespace std;
class Edge {
 public:
  int from, to, cap;
  double cost;
  int used;
  Edge(int from, int to, int cap, double cost)
      : from(from), to(to), cap(cap), cost(cost), used(0) {}
  int getOther(int a) const {
    if (a == from) {
      return to;
    } else if (a == to) {
      return from;
    }
    assert(false);
  }
  double getCost(int a) const {
    if (a == from) {
      return cost;
    } else if (a == to) {
      return -cost;
    }
    assert(false);
  }
  int getCap(int a) const {
    if (a == from) {
      return cap - used;
    } else if (a == to) {
      return used;
    }
    assert(false);
  }
  void sendFlow(int a, int amount) {
    if (a == from) {
      used += amount;
    } else if (a == to) {
      used -= amount;
    } else {
      assert(false);
    }
    assert(used >= 0);
    assert(used <= cap);
  }
};
const double inf = 1e18;
const double eps = 1e-9;
bool lt(double a, double b) { return a + eps < b; }
class MCMF {
 public:
  int n;
  vector<vector<shared_ptr<Edge>>> edges;
  MCMF(int numNodes) : n(numNodes), edges(n) {}
  void addEdge(int from, int to, int cap, double cost) {
    assert(from < n);
    assert(to < n);
    auto edge = make_shared<Edge>(from, to, cap, cost);
    edges[from].push_back(edge);
    edges[to].push_back(edge);
  }
  vector<shared_ptr<Edge>> shortestPathsLevi(int src) const {
    vector<shared_ptr<Edge>> pars(n, nullptr);
    vector<double> dist(n, inf);
    vector<int> m(n, 2);
    deque<int> q;
    dist[src] = 0.0;
    m[src] = 0;
    q.push_back(src);
    while (!q.empty()) {
      auto top = q.front();
      q.pop_front();
      m[top] = 0;
      for (auto& edge : edges[top]) {
        int other = edge->getOther(top);
        auto newDist = dist[top] + edge->getCost(top);
        if (edge->getCap(top) && lt(newDist, dist[other])) {
          dist[other] = newDist;
          pars[other] = edge;
          if (m[other] == 0) {
            q.push_front(other);
          } else if (m[other] == 2) {
            q.push_back(other);
          }
          m[other] = 1;
        }
      }
    }
    return pars;
  }
  vector<shared_ptr<Edge>> shortestPaths(int src) const {
    vector<double> dists(n, inf);
    vector<shared_ptr<Edge>> parents(n, nullptr);
    dists[src] = 0;
    for (int rep = 0; rep < n; rep++) {
      for (int i = 0; i < n; i++) {
        for (auto edge : edges[i]) {
          int other = edge->getOther(i);
          if (!edge->getCap(i)) {
            continue;
          }
          double newDist = dists[i] + edge->getCost(i);
          if (newDist < dists[other]) {
            dists[other] = newDist;
            parents[other] = edge;
          }
        }
      }
    }
    return parents;
  }
  pair<int, double> mcf(int src, int snk) const {
    int flow = 0;
    double cost = 0;
    while (true) {
      auto pars = shortestPathsLevi(src);
      if (!pars[snk]) {
        break;
      }
      int now = snk;
      int mnFlow = 123123123;
      while (now != src) {
        assert(pars[now] != nullptr);
        int otherNode = pars[now]->getOther(now);
        mnFlow = min(mnFlow, pars[now]->getCap(otherNode));
        now = otherNode;
      }
      flow += mnFlow;
      now = snk;
      while (now != src) {
        assert(pars[now] != nullptr);
        int otherNode = pars[now]->getOther(now);
        cost += pars[now]->getCost(otherNode) * mnFlow;
        pars[now]->sendFlow(otherNode, mnFlow);
        now = otherNode;
      }
    }
    return make_pair(flow, cost);
  }
};
double p2(double a) { return a * a; }
double dist(const pair<int, int>& a, const pair<int, int>& b) {
  return sqrt(p2(a.first - b.first) + p2(a.second - b.second));
}
int main() {
  int n;
  cin >> n;
  vector<pair<int, int>> points;
  for (int i = 0; i < n; i++) {
    int x, y;
    cin >> x >> y;
    points.emplace_back(x, y);
  }
  MCMF network(n * 2 + 2);
  int src = 0, snk = n * 2 + 1;
  for (int i = 0; i < n; i++) {
    network.addEdge(src, i + 1, 2, 0);
    network.addEdge(n + i + 1, snk, 1, 0);
    for (int j = 0; j < n; j++) {
      if (points[i].second > points[j].second) {
        network.addEdge(i + 1, n + j + 1, 1, dist(points[i], points[j]));
      }
    }
  }
  auto ans = network.mcf(src, snk);
  if (ans.first == n - 1) {
    cout << setprecision(10) << fixed << ans.second << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}
