Problem:
C: 成長する点 - Growing Point -
問題
粘菌コンピュータというものがある。
ある種の粘菌には「餌を求め、餌と餌の最短距離をつなぐ形に変形する」
という性質がある。
これを利用し、餌を「入力」、形を「出力」とみなして
コンピュータとして利用することができる。
今、二次元平面上に1つの粘菌の拠点と
N
個の餌が存在する。それぞれの餌には
1
から
N
までの異なる番号が与えられ、拠点には番号0が与えられている。
この粘菌はある餌を食べるために、その餌と最も近い拠点の最短距離を結ぶ管状に
成長し、食べた位置に新たに拠点を形成する。
新たに形成した拠点は拠点を形成する直前に食べた餌と同じ番号を持つ。
粘菌は拠点以外の場所から成長することはできない。
以降では、拠点と餌を二次元平面上の点、管状に成長した粘菌を複数の線分として考える。
すべての拠点と線分からなる構造を粘菌網と呼ぶ。
粘菌は1つの餌を食べるために次のような操作を繰り返す。
まだ食べていない餌の中で粘菌網に最も近い餌を選ぶ。そのような餌が複数存在する場合は番号が最も小さい餌を選ぶ。
選んだ餌と最も近い拠点を選ぶ。そのような拠点が複数存在する場合は、最も拠点の番号が小さいものから取る。
選んだ拠点と餌を結ぶ線分を引く。以降ではこのとき選んだ餌も拠点として扱う。
この粘菌は生きるために必要な栄養を取るのに
M
個の餌を食べる必要がある。
粘菌が
M
個の餌を食べるまでに引いたすべての線分の長さの合計を求めよ。
また、出力する値は0.0001以下の誤差を含んでいても良い。
以下の図では入力例2の粘菌の様子を示している。
入力形式
N
M
X
Y
px_1
py_1
...
px_n
py_n
1
行目には餌の数
N
（
1 \≤ N \≤ 5,000
）、食べる餌の個数
M
（
1 \≤ M \≤ N
）、番号0の拠点の座標
X
,
Y
（
−5,000 \≤ X, Y \≤ 5,000
）が整数値で与えられる。続く
N
行には番号順に餌の座標
px_i
,
py_i
（
1 \≤ i \≤ N
）が整数値で与えられる。（
−5,000 \≤ px_i, py_i \≤ 5,000
）
また、番号が異なる餌は異なる座標に存在し、それぞれの餌と番号0の拠点の座標は異なる。
出力形式
成長した距離の合計を1行で出力せよ。また、出力する値は0.0001以下の誤差を含んでいても良い。
入力例1
2 2 0 0
3 3
4 0
出力例1
7.16227766017
最初は番号1の餌と拠点の距離が $3\sqrt{2}$ と番号2の餌と拠点の距離が
4
なので
番号2の餌が選ばれる。その後番号1の餌と粘菌網との距離が
3
になり、番号1の餌が選ばれる。
入力例2
4 4 1 3
3 3
2 1
3 1
1 1
出力例2
6.2360679775
図のように餌1、2、4、3の順に粘菌は餌を食べていく
入力例3
16 15 -4077 763
-2480 2841
-2908 -1096
676 -4080
-4988 -2634
3004 -1360
-2272 1773
-4344 -3631
-355 4426
-3740 3634
-3330 2191
-3423 -2999
-3438 2281
4754 -1500
-3440 -3873
-2089 -3419
1426 2793
出力例3
25349.9626798834

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;

using LL = long long; using ll = LL;
using PII = pair<int, int>; using pii = PII;
using PLL = pair<LL, LL>; using pll = PLL;
using VI = vector<int>; using VL = vector<LL>;
const ll LINF = 1e18;
const int INF = 1e9;
#define FOR(i,s,t) for(int i =s; i < t;i++)
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(),a.end()

typedef double ld;
typedef complex<ld> Point;
const ld eps = 1e-9, pi = acos(-1.0);
namespace std {
	bool operator < (const Point& lhs, const Point& rhs) {
		if (lhs.real() < rhs.real() - eps) return true;
		if (lhs.real() < rhs.real() + eps) return false;
		return lhs.imag() < rhs.imag();
	}
}

class Line {
public:
	Point a, b;
	Line() :a(Point(0, 0)), b(Point(0, 0)) {}
	Line(Point a, Point b) :a(a), b(b) {}
	Point operator[](const int _num) {
		if (_num == 0) return a;
		else if (_num == 1) return b;
	}
};

ld dot(Point a, Point b) { return real(conj(a)*b); }
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
bool isis_sp(Line s, Point p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

void solve() {
	int N, M, X, Y; cin >> N >> M >> X >> Y;
	vector<int> flag(N+1, 0);
	vector<Point> ps(N+1);
	ps[0] = Point(X, Y); flag[0] = 1;
	for (int i = 1; i <= N; i++) {
		int a, b; cin >> a >> b;
		ps[i] = Point(a, b);
	}

	ld ans = 0;
	vector<double> dist(N + 1, LINF);
	for (int i = 0; i <= N; i++) {
		dist[i] = abs(ps[i] - ps[0]);
	}
	for (int i = 0; i < M; i++) {
		ld len = LINF;
		int idx = -1;
		for (int i = 0; i <= N; i++) {
			if (flag[i] == 1) continue;
			if (len > dist[i]) {
				len = dist[i];
				idx = i;
			}
		}

		len = LINF;
		int pidx = -1;
		for (int i = 0; i <= N; i++) {
			if (flag[i] == 1) {
				ld d = abs(ps[i] - ps[idx]);
				if (len > d) {
					len = d;
					pidx = i;
				}
			}
		}
		ans += abs(ps[idx] - ps[pidx]);
		flag[idx] = 1;
		Line L(ps[idx], ps[pidx]);
		for (int i = 0; i <= N; i++) {
			if (flag[i] == 1) continue;
			dist[i] = min(dist[i], dist_sp(L, ps[i]));
		}

	}
	cout << fixed << setprecision(12) << ans << endl;
}

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(false);

	solve();

	return 0;
}
accuracy: 1
time_ms: 1110
memory_kb: 3696
final_rank: 9

code_snippet: #include<iostream>
#include<cmath>

using namespace std;
#define ld long double
const ld EPS = 1e-8;
const int N = 5010;

struct Point {
    int x, y;

    Point (int x1 = 0, int y1 = 0) {
        x = x1, y = y1;
    }
};

struct Vector {
    int x, y;

    Vector(Point a, Point b) {
        x = b.x - a.x, y = b.y - a.y;
    }

    ld len() {
        return sqrtl(x * x + y * y);
    }

    int dot_prod(Vector v1) {
        return x * v1.x + y * v1.y;
    }

    int cross_prod(Vector v1) {
        return x * v1.y - y * v1.x;
    }
};

ld dist_point_point(Point a, Point b) {
    Vector ab(a, b);
    return ab.len();
}

ld dist_edg_point(Point a, Point b, Point p) {
    Vector ab(a, b), ba(b, a), ap(a, p), bp(b, p);
    if(ab.dot_prod(ap) < 0) return ap.len();
    if(ba.dot_prod(bp) < 0) return bp.len();
    return abs(ab.cross_prod(ap) / ab.len());
}

int n, m;
bool usd[N];
Point a[N];
ld ans = 0, d[N];

int main() {
#ifdef LOCAL
    freopen("inp.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    cin >> n >> m >> a[0].x >> a[0].y;
    for(int i = 1; i <= n; ++i) {
        cin >> a[i].x >> a[i].y;
        d[i] = dist_point_point(a[0], a[i]);
    }
    usd[0] = true;
    for(int i = 0; i < m; ++i) {
        int opt = -1;
        for(int j = 1; j <= n; ++j) {
            if(usd[j]) continue;
            if(opt == -1 || d[j] < d[opt] - EPS) opt = j;
        }
        int opt_usd = 0;
        for(int j = 0; j <= n; ++j) {
            if(usd[j]) {
                if(dist_point_point(a[j], a[opt]) < dist_point_point(a[opt_usd], a[opt])) {
                    opt_usd = j;
                }
            }
        }
        ans += dist_point_point(a[opt], a[opt_usd]);
        usd[opt] = true;
        for(int j = 1; j <= n; ++j) {
            if(!usd[j]) {
                d[j] = min(d[j], dist_edg_point(a[opt], a[opt_usd], a[j]));
            }
        }
    }
    cout.precision(11);
    cout << fixed << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 400
memory_kb: 3416
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/all
////////////////////////////////////////////////////////////////////////////////
typedef double Real;
const Real eps = 1e-8; // 1000 : 10^-8, 10000 : 10^-7
inline int sgn(Real a, Real b = 0) { return (a - b < -eps) ? -1 : (a - b > eps) ? 1 : 0; }
inline Real _sqrt(Real a) { return sqrt(max(a, (Real)0)); }
struct Point {
    Real x, y;
    Point() {}
    Point(Real x, Real y) : x(x), y(y) {}
    Point &operator-=(const Point &p) {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    Point &operator+=(const Point &p) {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &operator*=(Real d) {
        x *= d;
        y *= d;
        return *this;
    }
    Point &operator/=(Real d) {
        x /= d;
        y /= d;
        return *this;
    }
    Point operator+(const Point &p) const {
        Point res(*this);
        return res += p;
    }
    Point operator-(const Point &p) const {
        Point res(*this);
        return res -= p;
    }
    Point operator*(Real d) const {
        Point res(*this);
        return res *= d;
    }
    Point operator/(Real d) const {
        Point res(*this);
        return res /= d;
    }
    bool operator<(const Point &p) const {
        return (sgn(x, p.x) < 0 or (sgn(x, p.x) == 0 and sgn(y, p.y) < 0));
    }
    bool operator==(const Point &p) const { return (sgn(x - p.x) == 0 and sgn(y - p.y) == 0); }
    friend istream &operator>>(istream &is, Point &p) {
        is >> p.x >> p.y;
        return (is);
    }
    Real norm() { return _sqrt(x * x + y * y); }
    Real norm2() { return (x * x + y * y); }
    Point vec() { return (*this); }
    Point unit() { return (*this) / this->norm(); } // 単位ベクトル
    Point rotate(Real theta) {
        return {x * cos(theta) - y * sin(theta), x * sin(theta) + y * cos(theta)};
    }
    Point perpendicular() { return {-y, x}; }
    Point normal() { return perpendicular().unit(); } // 法線ベクトル
};

Point vec(Point a, Point b) { return (b - a); }
Real dist(Point a, Point b) { return vec(a, b).norm(); }
Real dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
Real cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }

// 線分
struct Segment : array<Point, 2> {
    Segment() {}
    Segment(Point a, Point b) { at(0) = a, at(1) = b; }
    Point vec() { return (at(1) - at(0)); }
    Real length() { return vec().norm(); }
    friend istream &operator>>(istream &is, Segment &s) {
        is >> s[0] >> s[1];
        return (is);
    }
};
// 直線
struct Line : Segment {
    Line() {}
    Line(Point a, Point b) : Segment(a, b) {}
    Line(Segment s) : Line(s[0], s[1]) {}
};

int ccw(Point a, Point b, Point c) {
    b -= a, c -= a;
    if (sgn(cross(b, c)) == 1) return 1;          // a,b,c 反時計回り
    if (sgn(cross(b, c)) == -1) return -1;        // a,b,c 時計周り
    if (sgn(dot(b, c)) == -1) return 2;           // c,a,b 一直線上
    if (sgn(c.norm() - b.norm()) == 1) return -2; // a,b,c 一直線上
    return 0;                                     // a,c,b 一直線上
}

// 垂直判定
template <typename T> bool is_orthogonal(T s, T t) { return sgn(dot(s.vec(), t.vec())) == 0; }
// 並行判定
template <typename T> bool is_parallel(T s, T t) { return sgn(cross(s.vec(), t.vec())) == 0; }
// 同一直線判定
template <typename T> bool is_same_line(T s, T t) {
    return abs(ccw(s[0], s[1], t[0])) != 1 and abs(ccw(s[0], s[1], t[1])) != 1;
}
// 線分上の点判定
bool is_on_segment(Point p, Segment l) { return ccw(l[0], l[1], p) == 0; }
// 線分の交差判定(AOJ-2172)
bool is_intersect(Segment s, Segment t) {
    return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 and
           ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
// 2直線の交点(AOJ-2596)
pair<bool, Point> line_intersection(Line s, Line t) {
    if (is_same_line(s, t)) return {true, s[0]};
    else if (is_parallel(s, t)) return {false, Point()};
    else return {true, s[0] + s.vec() * cross(t[0] - s[0], t.vec()) / cross(s.vec(), t.vec())};
}
// 2線分の交点
pair<bool, Point> segment_intersection(Segment s, Segment t) {
    if (is_same_line(s, t)) {
        if (is_on_segment(s[0], t)) return {true, s[0]};
        else if (is_on_segment(s[1], t)) return {true, s[1]};
        else if (is_on_segment(t[0], s)) return {true, t[0]};
        else return {false, Point()};
    }
    if (!is_intersect(s, t)) return {false, Point()};
    else return line_intersection(Line(s), Line(t));
}
// 点と直線の距離
Real point_line_distance(Point p, Line l) { return abs(cross(p - l[0], l.vec())) / l.length(); }
// 点と線分の距離
Real point_segment_distance(Point p, Segment l) {
    if (sgn(dot(p - l[0], l.vec())) == -1) return dist(p, l[0]);
    else if (sgn(dot(p - l[1], l.vec())) == 1) return dist(p, l[1]);
    else return point_line_distance(p, l);
}
// 線分と線分の距離(AOJ-1157)
Real segment_segment_distance(Segment s, Segment t) {
    if (is_intersect(s, t)) return 0;
    double res = point_segment_distance(s[0], t);
    res = min(res, point_segment_distance(s[1], t));
    res = min(res, point_segment_distance(t[0], s));
    res = min(res, point_segment_distance(t[1], s));
    return res;
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    vector<Point> p(n + 1);
    vector<double> dist(n + 1);
    vector<bool> used(n + 1);
    for (int i = 0; i <= n; ++i) {
        cin >> p[i];
    }
    used[0] = true;
    for (int i = 0; i <= n; ++i) {
        dist[i] = (p[0] - p[i]).norm();
    }
    double res = 0;
    for (int i = 0; i < m; ++i) {
        int idx = -1;
        for (int j = 0; j <= n; ++j) {
            if (used[j]) continue;
            if (idx == -1) idx = j;
            if (dist[j] < dist[idx]) idx = j;
        }
        int base = -1;
        double cost = 1e9;
        for (int j = 0; j <= n; ++j) {
            if (!used[j]) continue;
            double d = (p[j] - p[idx]).norm();
            if (d < cost) {
                cost = d;
                base = j;
            }
        }
        res += cost;
        used[idx] = true;
        Segment s = Segment(p[base], p[idx]);
        for (int j = 0; j <= n; ++j) {
            dist[j] = min(dist[j], point_segment_distance(p[j], s));
        }
    }
    printf("%.9f\n", res);
}
accuracy: 1
time_ms: 240
memory_kb: 3664
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

// arg(x) : argment,[-PI,PI]
using CP = complex<long double>;
#define X real()
#define Y imag()
const long double PI = acos(-1.0L);
const long double EPS = 1e-10;
bool operator==(const CP &l, const CP &r) { return norm(l - r) <= EPS; }
struct Circle {
  CP o;
  long double r;
  Circle(long double _x = 0.0L, long double _y = 0.0L, long double _r = 0.0L)
      : o(CP(_x, _y)), r(_r) {}
  Circle(CP _o, long double _r = 0.0) : o(_o), r(_r) {}
  bool operator<(const Circle &cr) const { return r < cr.r; }
};

struct Line {
  CP s, t;
  Line(long double sx = 0.0L, long double sy = 0.0L, long double tx = 0.0L,
       long double ty = 0.0L)
      : s(CP(sx, sy)), t(CP(tx, ty)) {}
  Line(CP _s, CP _t) : s(_s), t(_t) {}
};

// cos a
long double costh(const long double &a, const long double &b,
                  const long double &c) {
  return (b * b - a * a + c * c) / (2.0L * b * c);
}

// dot(a,b) = |a||b|cos x
long double dot(const CP &a, const CP &b) { return (conj(a) * b).X; }
// cross(a,b) : area of parallelogram
// sign : a-> b ,counter clockwise? + : -
long double cross(const CP &a, const CP &b) { return (conj(a) * b).Y; }
long double corner(const CP &a, const CP &b) {
  //[0,PI]
  return acos(dot(a, b) / (abs(a) * abs(b)));
}

CP projectionLP(const CP &s, const CP &t, const CP &p) {
  if (s == t) return s;
  CP base = t - s;
  long double r = dot(p - s, base) / norm(base);
  return s + base * r;
}
CP projectionLP(const Line &l, const CP &p) {
  return projectionLP(l.s, l.t, p);
}

CP reflectionLP(const CP &s, const CP &t, const CP &p) {
  CP tmp = (projectionLP(s, t, p) - p);
  tmp *= 2;
  return p + tmp;
}
CP reflectionLP(const Line &l, const CP &p) {
  return reflectionLP(l.s, l.t, p);
}

int calc_clockwiseSP(const CP &s, CP t, CP p) {
  t -= s;
  p -= s;
  if (cross(t, p) > EPS) return 1;    // "COUNTER_CLOCKWISE"
  if (cross(t, p) < -EPS) return -1;  //"CLOCK_WISE"
  if (dot(t, p) < 0) return 2;        // "ONLINE_BACK"
  if (norm(t) < norm(p)) return -2;   // "ONLINE_FRONT"
  return 0;                           // "ON_SEGMENT"
}
int calc_clockwiseSP(const Line &l, const CP &p) {
  return calc_clockwiseSP(l.s, l.t, p);
}

int parallel_orthogonalLL(const CP &s, CP t, const CP &a, CP b) {
  t -= s;
  b -= a;
  if (abs(cross(t, b)) <= EPS) return 2;  // "parallel"
  if (abs(dot(t, b)) <= EPS) return 1;    // "orthogonal"
  return 0;
}
int parallel_orthogonalLL(const Line &ll, const Line &lr) {
  return parallel_orthogonalLL(ll.s, ll.t, lr.s, lr.t);
}

CP intersectionLL(const CP &a, const CP &b, const CP &c, const CP &d) {
  return a + (b - a) * (cross(d - c, c - a) / cross(d - c, b - a));
}
CP intersectionLL(const Line &ll, const Line &lr) {
  return intersectionLL(ll.s, ll.t, lr.s, lr.t);
}

bool on_segSP(const CP &s, const CP &t, const CP &p) {
  // if not use end point, dot(s - p, t - p) < 0
  return abs(cross(s - p, t - p)) <= EPS && dot(s - p, t - p) <= 0;
}
bool on_segSP(const Line &l, const CP &p) { return on_segSP(l.s, l.t, p); }

// crossing segments? (a,b) and (c,d)
bool iscrossSS(const CP &a, const CP &b, const CP &c, const CP &d) {
  // parallel
  if (abs(cross(a - b, c - d)) <= EPS) {
    return on_segSP(a, b, c) || on_segSP(a, b, d) || on_segSP(c, d, a) ||
           on_segSP(c, d, b);
  }
  CP isp = intersectionLL(a, b, c, d);
  return on_segSP(a, b, isp) && on_segSP(c, d, isp);
}
bool iscrossSS(const Line &ll, const Line &lr) {
  return iscrossSS(ll.s, ll.t, lr.s, lr.t);
}

long double distLP(const CP &s, const CP &t, const CP &p) {
  return abs(cross(t - s, p - s) / abs(t - s));
}
long double distLP(const Line &l, const CP &p) { return distLP(l.s, l.t, p); }

long double distSP(const CP &s, const CP &t, const CP &p) {
  if (dot(t - s, p - s) < 0) return abs(p - s);
  if (dot(s - t, p - t) < 0) return abs(p - t);
  return distLP(s, t, p);
}
long double distSP(const Line &l, const CP &p) { return distSP(l.s, l.t, p); }

using P = pair<long double, int>;

int n, m;
vector<CP> v;

long double solve();

int main() {
  cin >> n >> m, ++n;
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    v.emplace_back(x, y);
  }
  cout << fixed << setprecision(10);
  cout << solve() << endl;
  return 0;
}

long double solve() {
  vector<long double> memo(n, 1e10);
  for (int i = 1; i < n; ++i) memo[i] = abs(v[i] - v[0]);
  memo[0] = -1;
  long double res = 0;
  while (m--) {
    long double nd = 1e10;
    int now = 0;
    for (int i = 0; i < n; ++i)
      if (memo[i] > 0 && memo[i] < nd) now = i, nd = memo[i];
    int from = 0;
    nd = 1e10;
    for (int i = 0; i < n; ++i)
      if (memo[i] < 0 && abs(v[now] - v[i]) < nd)
        from = i, nd = abs(v[now] - v[i]);
    res += nd;
    memo[now] = -1;
    for (int i = 0; i < n; ++i)
      if (memo[i] > 0) memo[i] = min(memo[i], distSP(v[from], v[now], v[i]));
  }
  return res;
}
accuracy: 1
time_ms: 1350
memory_kb: 3744
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

// arg(x) : argment,[-PI,PI]
using CP = complex<long double>;
#define X real()
#define Y imag()
const long double PI = acos(-1.0L);
const long double EPS = 1e-10;
bool operator==(const CP &l, const CP &r) { return norm(l - r) <= EPS; }
struct Circle {
  CP o;
  long double r;
  Circle(long double _x = 0.0L, long double _y = 0.0L, long double _r = 0.0L)
      : o(CP(_x, _y)), r(_r) {}
  Circle(CP _o, long double _r = 0.0) : o(_o), r(_r) {}
  bool operator<(const Circle &cr) const { return r < cr.r; }
};

struct Line {
  CP s, t;
  Line(long double sx = 0.0L, long double sy = 0.0L, long double tx = 0.0L,
       long double ty = 0.0L)
      : s(CP(sx, sy)), t(CP(tx, ty)) {}
  Line(CP _s, CP _t) : s(_s), t(_t) {}
};

// cos a
long double costh(const long double &a, const long double &b,
                  const long double &c) {
  return (b * b - a * a + c * c) / (2.0L * b * c);
}

// dot(a,b) = |a||b|cos x
long double dot(const CP &a, const CP &b) { return (conj(a) * b).X; }
// cross(a,b) : area of parallelogram
// sign : a-> b ,counter clockwise? + : -
long double cross(const CP &a, const CP &b) { return (conj(a) * b).Y; }
long double corner(const CP &a, const CP &b) {
  //[0,PI]
  return acos(dot(a, b) / (abs(a) * abs(b)));
}

CP projectionLP(const CP &s, const CP &t, const CP &p) {
  if (s == t) return s;
  CP base = t - s;
  long double r = dot(p - s, base) / norm(base);
  return s + base * r;
}
CP projectionLP(const Line &l, const CP &p) {
  return projectionLP(l.s, l.t, p);
}

CP reflectionLP(const CP &s, const CP &t, const CP &p) {
  CP tmp = (projectionLP(s, t, p) - p);
  tmp *= 2;
  return p + tmp;
}
CP reflectionLP(const Line &l, const CP &p) {
  return reflectionLP(l.s, l.t, p);
}

int calc_clockwiseSP(const CP &s, CP t, CP p) {
  t -= s;
  p -= s;
  if (cross(t, p) > EPS) return 1;    // "COUNTER_CLOCKWISE"
  if (cross(t, p) < -EPS) return -1;  //"CLOCK_WISE"
  if (dot(t, p) < 0) return 2;        // "ONLINE_BACK"
  if (norm(t) < norm(p)) return -2;   // "ONLINE_FRONT"
  return 0;                           // "ON_SEGMENT"
}
int calc_clockwiseSP(const Line &l, const CP &p) {
  return calc_clockwiseSP(l.s, l.t, p);
}

int parallel_orthogonalLL(const CP &s, CP t, const CP &a, CP b) {
  t -= s;
  b -= a;
  if (abs(cross(t, b)) <= EPS) return 2;  // "parallel"
  if (abs(dot(t, b)) <= EPS) return 1;    // "orthogonal"
  return 0;
}
int parallel_orthogonalLL(const Line &ll, const Line &lr) {
  return parallel_orthogonalLL(ll.s, ll.t, lr.s, lr.t);
}

CP intersectionLL(const CP &a, const CP &b, const CP &c, const CP &d) {
  return a + (b - a) * (cross(d - c, c - a) / cross(d - c, b - a));
}
CP intersectionLL(const Line &ll, const Line &lr) {
  return intersectionLL(ll.s, ll.t, lr.s, lr.t);
}

bool on_segSP(const CP &s, const CP &t, const CP &p) {
  // if not use end point, dot(s - p, t - p) < 0
  return abs(cross(s - p, t - p)) <= EPS && dot(s - p, t - p) <= 0;
}
bool on_segSP(const Line &l, const CP &p) { return on_segSP(l.s, l.t, p); }

// crossing segments? (a,b) and (c,d)
bool iscrossSS(const CP &a, const CP &b, const CP &c, const CP &d) {
  // parallel
  if (abs(cross(a - b, c - d)) <= EPS) {
    return on_segSP(a, b, c) || on_segSP(a, b, d) || on_segSP(c, d, a) ||
           on_segSP(c, d, b);
  }
  CP isp = intersectionLL(a, b, c, d);
  return on_segSP(a, b, isp) && on_segSP(c, d, isp);
}
bool iscrossSS(const Line &ll, const Line &lr) {
  return iscrossSS(ll.s, ll.t, lr.s, lr.t);
}

long double distLP(const CP &s, const CP &t, const CP &p) {
  return abs(cross(t - s, p - s) / abs(t - s));
}
long double distLP(const Line &l, const CP &p) { return distLP(l.s, l.t, p); }

long double distSP(const CP &s, const CP &t, const CP &p) {
  if (dot(t - s, p - s) < 0) return abs(p - s);
  if (dot(s - t, p - t) < 0) return abs(p - t);
  return distLP(s, t, p);
}
long double distSP(const Line &l, const CP &p) { return distSP(l.s, l.t, p); }

using P = pair<long double, int>;

int n, m;
vector<CP> v;

long double solve();

int main() {
  cin >> n >> m, ++n;
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    v.emplace_back(x, y);
  }
  cout << fixed << setprecision(10);
  cout << solve() << endl;
  return 0;
}

long double solve() {
  //   vector<vector<long double>> dist(n, vector<long double>(n, 0));
  vector<long double> memo(n, 1e10);
  {
    // for (int i = 0; i < n; ++i)
    //   for (int j = 0; j < n; ++j) dist[i][j] = abs(v[i] - v[j]);
    for (int i = 1; i < n; ++i) memo[i] = abs(v[i] - v[0]);
    memo[0] = -1;
  }
  long double res = 0;
  while (m--) {
    long double nd = 1e10;
    int now = 0;
    for (int i = 0; i < n; ++i)
      if (memo[i] > 0 && memo[i] < nd) now = i, nd = memo[i];
    int from = 0;
    nd = 1e10;
    for (int i = 0; i < n; ++i)
      if (memo[i] < 0 && abs(v[now] - v[i]) < nd)
        from = i, nd = abs(v[now] - v[i]);
    res += nd;
    memo[now] = -1;
    for (int i = 0; i < n; ++i)
      if (memo[i] > 0) memo[i] = min(memo[i], distSP(v[from], v[now], v[i]));
  }
  return res;
}
accuracy: 1
time_ms: 1350
memory_kb: 3744
final_rank: 12

code_snippet: #line 1 "c.cpp"
#pragma region Macros
#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define FOR(i, a, b) for(int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

void Case(int i) { cout << "Case #" << i << ": "; }
#pragma endregion Macros

#line 1 "/home/siro53/kyo-pro/compro_library/geometry/geometry.hpp"
namespace geometry {
    // Point : 複素数型を位置ベクトルとして扱う
    // 実軸(real)をx軸、挙軸(imag)をy軸として見る
    using D = double;
    using Point = complex<D>;
    const D EPS = 1e-7;
    const D PI = acosl(-1);

    inline bool equal(const D &a, const D &b) { return fabs(a - b) < EPS; }

    // 単位ベクトル(unit vector)を求める
    Point unitVector(const Point &a) { return a / abs(a); }

    // 法線ベクトル(normal vector)を求める
    // 90度回転した単位ベクトルをかける
    // -90度がよければPoint(0, -1)をかける
    Point normalVector(const Point &a) { return a * Point(0, 1); }

    // 内積(dot product) : a・b = |a||b|cosΘ
    D dot(const Point &a, const Point &b) {
        return (a.real() * b.real() + a.imag() * b.imag());
    }

    // 外積(cross product) : a×b = |a||b|sinΘ
    D cross(const Point &a, const Point &b) {
        return (a.real() * b.imag() - a.imag() * b.real());
    }

    // 点pを反時計回りにtheta度回転
    // thetaはラジアン！！！
    Point rotate(const Point &p, const D &theta) {
        return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                     sin(theta) * p.real() + cos(theta) * p.imag());
    }

    // ラジアン->度
    D radianToDegree(const D &radian) { return radian * 180.0 / PI; }

    // 度->ラジアン
    D degreeToRadian(const D &degree) { return degree * PI / 180.0; }

    // 点の回転方向
    // 点a, b, cの位置関係について(aが基準点)
    int ccw(const Point &a, Point b, Point c) {
        b -= a, c -= a;
        // 点a, b, c が
        // 反時計回りの時、
        if(cross(b, c) > EPS) return 1;
        // 時計回りの時、
        if(cross(b, c) < -EPS) return -1;
        // c, a, bがこの順番で同一直線上にある時、
        if(dot(b, c) < 0) return 2;
        // a, b, cがこの順番で同一直線上にある場合、
        if(norm(b) < norm(c)) return -2;
        // cが線分ab上にある場合、
        return 0;
    }

    // Line : 直線を表す構造体
    // b - a で直線・線分を表せる
    struct Line {
        Point a, b;
        Line() = default;
        Line(Point a, Point b) : a(a), b(b) {}
        // Ax+By=C
        Line(D A, D B, D C) {
            if(equal(A, 0)) {
                a = Point(0, C / B), b = Point(1, C / B);
            } else if(equal(B, 0)) {
                b = Point(C / A, 0), b = Point(C / A, 1);
            } else {
                a = Point(0, C / B), b = Point(C / A, 0);
            }
        }
    };

    // Segment : 線分を表す構造体
    // Lineと同じ
    struct Segment : Line {
        Segment() = default;

        Segment(Point a, Point b) : Line(a, b) {}
    };

    // Circle : 円を表す構造体
    // pが中心の位置ベクトル、rは半径
    struct Circle {
        Point p;
        D r;

        Circle() = default;

        Circle(Point p, D r) : p(p), r(r) {}
    };

    // 2直線の直交判定 : a⊥b <=> dot(a, b) = 0
    bool isOrthogonal(const Line &a, const Line &b) {
        return equal(dot(a.b - a.a, b.b - b.a), 0);
    }
    // 2直線の平行判定 : a//b <=> cross(a, b) = 0
    bool isParallel(const Line &a, const Line &b) {
        return equal(cross(a.b - a.a, b.b - b.a), 0);
    }

    // 点cが直線ab上にあるか
    bool isPointOnLine(const Point &a, const Point &b, const Point &c) {
        return isParallel(Line(a, b), Line(a, c));
    }

    // 点cが"線分"ab上にあるか
    bool isPointOnSegment(const Point &a, const Point &b, const Point &c) {
        // |a-c| + |c-b| <= |a-b| なら線分上
        return (abs(a - c) + abs(c - b) < abs(a - b) + EPS);
    }

    // 直線lと点pの距離を求める
    D distanceBetweenLineAndPoint(const Line &l, const Point &p) {
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 線分lと点pの距離を求める
    // 定義：点pから「線分lのどこか」への最短距離
    D distanceBetweenSegmentAndPoint(const Segment &l, const Point &p) {
        if(dot(l.b - l.a, p - l.a) < EPS) return abs(p - l.a);
        if(dot(l.a - l.b, p - l.b) < EPS) return abs(p - l.b);
        return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
    }

    // 直線s, tの交点の計算
    Point crossPoint(const Line &s, const Line &t) {
        D d1 = cross(s.b - s.a, t.b - t.a);
        D d2 = cross(s.b - s.a, s.b - t.a);
        if(equal(abs(d1), 0) && equal(abs(d2), 0)) return t.a;
        return t.a + (t.b - t.a) * (d2 / d1);
    }

    // 線分s, tの交点の計算
    Point crossPoint(const Segment &s, const Segment &t) {
        return crossPoint(Line(s), Line(t));
    }

    // 線分sと線分tが交差しているかどうか
    // bound:線分の端点を含むか
    bool isIntersect(const Segment &s, const Segment &t, bool bound) {
        return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) < bound &&
               ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) < bound;
    }

    // 線分sとtの距離
    D distanceBetweenSegments(const Segment &s, const Segment &t) {
        if(isIntersect(s, t, 1)) return (D)(0);
        D ans = distanceBetweenSegmentAndPoint(s, t.a);
        chmin(ans, distanceBetweenSegmentAndPoint(s, t.b));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.a));
        chmin(ans, distanceBetweenSegmentAndPoint(t, s.b));
        return ans;
    }

    // 射影(projection)
    // 直線(線分)lに点pから引いた垂線の足を求める
    Point projection(const Line &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    Point projection(const Segment &l, const Point &p) {
        D t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }

    // 反射(reflection)
    // 直線lを対称軸として点pと線対称の位置にある点を求める
    Point reflection(const Line &l, const Point &p) {
        return p + (projection(l, p) - p) * (D)2.0;
    }

    // 2つの円の交差判定
    // 返り値は共通接線の数
    int isIntersect(const Circle &c1, const Circle &c2) {
        D d = abs(c1.p - c2.p);
        // 2つの円が離れている場合
        if(d > c1.r + c2.r + EPS) return 4;
        // 外接している場合
        if(equal(d, c1.r + c2.r)) return 3;
        // 内接している場合
        if(equal(d, abs(c1.r - c2.r))) return 1;
        // 内包している場合
        if(d < abs(c1.r - c2.r) - EPS) return 0;
        return 2;
    }

    // 2つの円の交点
    vector<Point> crossPoint(const Circle &c1, const Circle &c2) {
        vector<Point> res;
        int mode = isIntersect(c1, c2);
        // 2つの中心の距離
        D d = abs(c1.p - c2.p);
        // 2円が離れている場合
        if(mode == 4) return res;
        // 1つの円がもう1つの円に内包されている場合
        if(mode == 0) return res;
        // 2円が外接する場合
        if(mode == 3) {
            D t = c1.r / (c1.r + c2.r);
            res.emplace_back(c1.p + (c2.p - c1.p) * t);
            return res;
        }
        // 内接している場合
        if(mode == 1) {
            if(c2.r < c1.r - EPS) {
                res.emplace_back(c1.p + (c2.p - c1.p) * (c1.r / d));
            } else {
                res.emplace_back(c2.p + (c1.p - c2.p) * (c2.r / d));
            }
            return res;
        }
        // 2円が重なる場合
        D rc1 = (c1.r * c1.r + d * d - c2.r * c2.r) / (2 * d);
        D rs1 = sqrt(c1.r * c1.r - rc1 * rc1);
        if(c1.r - abs(rc1) < EPS) rs1 = 0;
        Point e12 = (c2.p - c1.p) / abs(c2.p - c1.p);
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, 1));
        res.emplace_back(c1.p + rc1 * e12 + rs1 * e12 * Point(0, -1));
        return res;
    }

    // 点pが円cの内部(円周上も含む)に入っているかどうか
    bool isInCircle(const Circle &c, const Point &p) {
        D d = abs(c.p - p);
        return (equal(d, c.r) || d < c.r - EPS);
    }

    // 円cと直線lの交点
    vector<Point> crossPoint(const Circle &c, const Line &l) {
        vector<Point> res;
        D d = distanceBetweenLineAndPoint(l, c.p);
        // 交点を持たない
        if(d > c.r + EPS) return res;
        // 接する
        Point h = projection(l, c.p);
        if(equal(d, c.r)) {
            res.emplace_back(h);
            return res;
        }
        Point e = unitVector(l.b - l.a);
        D ph = sqrt(c.r * c.r - d * d);
        res.emplace_back(h - e * ph);
        res.emplace_back(h + e * ph);
        return res;
    }

    // 点pを通る円cの接線
    // 2本あるので、接点のみを返す
    vector<Point> tangentToCircle(const Point &p, const Circle &c) {
        return crossPoint(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
    }

    // 円の共通接線
    vector<Line> tangent(const Circle &a, const Circle &b) {
        vector<Line> ret;
        // 2円の中心間の距離
        D g = abs(a.p - b.p);
        // 円が内包されている場合
        if(equal(g, 0)) return ret;
        Point u = unitVector(b.p - a.p);
        Point v = rotate(u, PI / 2);
        for(int s : {-1, 1}) {
            D h = (a.r + b.r * s) / g;
            if(equal(h * h, 1)) {
                ret.emplace_back(a.p + (h > 0 ? u : -u) * a.r,
                                 a.p + (h > 0 ? u : -u) * a.r + v);

            } else if(1 - h * h > 0) {
                Point U = u * h, V = v * sqrt(1 - h * h);
                ret.emplace_back(a.p + (U + V) * a.r,
                                 b.p - (U + V) * (b.r * s));
                ret.emplace_back(a.p + (U - V) * a.r,
                                 b.p - (U - V) * (b.r * s));
            }
        }
        return ret;
    }

    // 多角形の面積を求める
    D PolygonArea(const vector<Point> &p) {
        D res = 0;
        int n = p.size();
        for(int i = 0; i < n - 1; i++) res += cross(p[i], p[i + 1]);
        res += cross(p[n - 1], p[0]);
        return res * 0.5;
    }

    // 凸多角形かどうか
    bool isConvex(const vector<Point> &p) {
        int n = p.size();
        int now, pre, nxt;
        for(int i = 0; i < n; i++) {
            pre = (i - 1 + n) % n;
            nxt = (i + 1) % n;
            now = i;
            if(ccw(p[pre], p[now], p[nxt]) == -1) return false;
        }
        return true;
    }

    // 凸包 O(NlogN)
    vector<Point> ConvexHull(vector<Point> &p) {
        int n = (int)p.size(), k = 0;
        sort(ALL(p), [](const Point &a, const Point &b) {
            return (real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b));
        });
        vector<Point> ch(2 * n);
        // 一直線上の3点を含める -> (< -EPS)
        // 含め無い -> (< EPS)
        for(int i = 0; i < n; ch[k++] = p[i++]) { // lower
            while(k >= 2 &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) { // upper
            while(k >= t &&
                  cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < EPS)
                --k;
        }
        ch.resize(k - 1);
        return ch;
    }

    // 多角形gに点pが含まれているか?
    // 含まれる:2, 辺上にある:1, 含まれない:0
    int isContained(const vector<Point> &g, const Point &p) {
        bool in = false;
        int n = (int)g.size();
        for(int i = 0; i < n; i++) {
            Point a = g[i] - p, b = g[(i + 1) % n] - p;
            if(imag(a) > imag(b)) swap(a, b);
            if(imag(a) <= EPS && EPS < imag(b) && cross(a, b) < -EPS) in = !in;
            if(cross(a, b) == 0 && dot(a, b) <= 0) return 1;
        }
        return (in ? 2 : 0);
    }

} // namespace geometry
#line 70 "c.cpp"
using namespace geometry;

using Data = pair<D, int>;

int main() {
    int N, M;
    cin >> N >> M;
    vector<Point> p(N+1); 
    REP(i, N+1) {
        int x, y;
        cin >> x >> y;
        p[i] = Point(x, y);
    }

    D ans = 0;
    set<Data> unused; // まだ追加してない頂点
    set<int> used; // すでに追加した頂点
    REP(i, N) unused.emplace(abs(p[0] - p[i+1]), i+1);
    used.insert(0);

    REP(_, M) {
        // 次の餌を選ぶ
        auto [nxt_d, nxt_id] = *unused.begin();
        // 餌と最も近い拠点を求める
        int min_kyoten = -1;
        D mn = LLINF;
        for(int id : used) if(chmin(mn, abs(p[nxt_id] - p[id]))) min_kyoten = id;
        ans += mn;
        Segment seg(p[nxt_id], p[min_kyoten]);
        // まだ追加してない頂点の最短距離を更新
        set<Data> newse;
        for(auto& [d, id] : unused) {
            if(id == nxt_id) continue;
            D nd = min(d, distanceBetweenSegmentAndPoint(seg, p[id]));
            newse.emplace(nd, id);
        }
        unused = newse;
        used.insert(nxt_id);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 1690
memory_kb: 4268
final_rank: 15

code_snippet: #line 2 "cpplib/util/template.hpp"
/**
 * These codes are licensed under CC0.
 * http://creativecommons.org/publicdomain/zero/1.0/deed.ja
 */
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
const vector<lint> dx={1,0,-1,0,1,1,-1,-1};
const vector<lint> dy={0,1,0,-1,1,-1,1,-1};
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;
template<typename T,typename E>ostream& operator<<(ostream& out,pair<T,E>v){out<<"("<<v.first<<","<<v.second<<")";return out;}
#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 2 "code.cpp"

int main(){
    lint n,m,x,y;
    cin>>n>>m>>x>>y;
    vec px(n),py(n);
    rep(i,n){
        cin>>px[i]>>py[i];
    }
    px.emplace_back(x);
    py.emplace_back(y);
    vector<pair<__int128_t,__int128_t>>score(n+1,make_pair(INF,1));
    set<lint> s;
    s.emplace(n);
    auto f=[&](lint i,lint j)->lint{
        return (px[j]-px[i])*(px[j]-px[i])+(py[j]-py[i])*(py[j]-py[i]);
    };
    auto g=[&](lint i,lint j,lint k)->pair<__int128_t,__int128_t>{
        lint a=py[i]-py[j];
        lint b=-(px[i]-px[j]);
        lint c=-(a*px[i]+b*py[i]);
        pair<lint,lint> tmp=make_pair((a*px[k]+b*py[k]+c)*(a*px[k]+b*py[k]+c),(a*a+b*b));
        if((px[j]-px[i])*(px[k]-px[i])+(py[j]-py[i])*(py[k]-py[i])>=0
            && (px[i]-px[j])*(px[k]-px[j])+(py[i]-py[j])*(py[k]-py[j])>=0
            )return tmp;
        else return min(make_pair(f(i,k),1LL),make_pair(f(j,k),1LL));
    };
    long double ans=0;
    auto chmin=[&](pair<__int128_t,__int128_t>&s,const pair<__int128_t,__int128_t>&t)->bool{
        if(s.first*t.second>t.first*s.second){
            s=t;
            return 1;
        }
        return 0;
    };
    rep(i,n){
        chmin(score[i],make_pair(f(i,n),1LL));
    }
    while(m--){
        pair<__int128_t,__int128_t> mn2=make_pair(INF,1LL);
        lint k=0;
        rep(i,n){
            if(chmin(mn2,score[i])){
                k=i;
            }
        }
        pair<__int128_t,__int128_t> mn=make_pair(INF,1LL);
        lint idx=0;
        for(auto j:s){
            if(chmin(mn,make_pair(f(j,k),1LL))){
                idx=j;
            }
        }
        ans+=sqrtl(f(k,idx));
        s.emplace(k);
        score[k]=make_pair(INF,1LL);
        rep(i,n){
            if(!s.count(i)){
                chmin(score[i],g(k,idx,i));
            }
        }
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 1330
memory_kb: 3856
final_rank: 11

code_snippet: #line 2 "cpplib/util/template.hpp"
/**
 * These codes are licensed under CC0.
 * http://creativecommons.org/publicdomain/zero/1.0/deed.ja
 */
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
const vector<lint> dx={1,0,-1,0,1,1,-1,-1};
const vector<lint> dy={0,1,0,-1,1,-1,1,-1};
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;
template<typename T,typename E>ostream& operator<<(ostream& out,pair<T,E>v){out<<"("<<v.first<<","<<v.second<<")";return out;}
#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 2 "code.cpp"

int main(){
    lint n,m,x,y;
    cin>>n>>m>>x>>y;
    vec px(n),py(n);
    rep(i,n){
        cin>>px[i]>>py[i];
    }
    px.emplace_back(x);
    py.emplace_back(y);
    vector<lint>score(n+1,INF);
    set<lint> s;
    s.emplace(n);
    auto f=[&](lint i,lint j)->lint{
        return (px[j]-px[i])*(px[j]-px[i])+(py[j]-py[i])*(py[j]-py[i]);
    };
    auto g=[&](lint i,lint j,lint k)->lint{
        lint a=py[i]-py[j];
        lint b=-(px[i]-px[j]);
        lint c=-(a*px[i]+b*py[i]);
        lint tmp=(a*px[k]+b*py[k]+c)*(a*px[k]+b*py[k]+c)/(a*a+b*b);
        if((px[j]-px[i])*(px[k]-px[i])+(py[j]-py[i])*(py[k]-py[i])>=0
            && (px[i]-px[j])*(px[k]-px[j])+(py[i]-py[j])*(py[k]-py[j])>=0
            )return tmp;
        else return min(f(i,k),f(j,k));
    };
    long double ans=0;
    rep(i,n){
        chmin(score[i],f(i,n));
    }
    while(m--){
        lint mn2=INF,k=0;
        rep(i,n){
            if(chmin(mn2,score[i])){
                k=i;
            }
        }
        lint mn=INF,idx=0;
        for(auto j:s){
            if(chmin(mn,f(j,k))){
                idx=j;
            }
        }
        ans+=sqrtl(f(k,idx));
        s.emplace(k);
        score[k]=INF;
        rep(i,n){
            if(!s.count(i)){
                chmin(score[i],g(k,idx,i));
            }
        }
    }
    cout<<ans<<endl;
}
accuracy: 0.5
time_ms: 970
memory_kb: 3732
final_rank: 19

code_snippet: #line 2 "cpplib/util/template.hpp"
/**
 * These codes are licensed under CC0.
 * http://creativecommons.org/publicdomain/zero/1.0/deed.ja
 */
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
const vector<lint> dx={1,0,-1,0,1,1,-1,-1};
const vector<lint> dy={0,1,0,-1,1,-1,1,-1};
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;
template<typename T,typename E>ostream& operator<<(ostream& out,pair<T,E>v){out<<"("<<v.first<<","<<v.second<<")";return out;}
#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 2 "code.cpp"

int main(){
    lint n,m,x,y;
    cin>>n>>m>>x>>y;
    vec px(n),py(n);
    rep(i,n){
        cin>>px[i]>>py[i];
    }
    px.emplace_back(x);
    py.emplace_back(y);
    vector<lint>score(n+1,INF);
    set<lint> s;
    s.emplace(n);
    auto f=[&](lint i,lint j)->lint{
        return (px[j]-px[i])*(px[j]-px[i])+(py[j]-py[i])*(py[j]-py[i]);
    };
    auto g=[&](lint i,lint j,lint k)->lint{
        lint a=py[i]-py[j];
        lint b=-(px[i]-px[j]);
        lint c=-(a*px[i]+b*py[i]);
        lint tmp=(a*px[k]+b*py[k]+c)*(a*px[k]+b*py[k]+c)/(a*a+b*b);
        if((px[j]-px[i])*(px[k]-px[i])+(py[j]-py[i])*(py[k]-py[i])>=0
            && (px[i]-px[j])*(px[k]-px[j])+(py[i]-py[j])*(py[k]-py[j])>=0
            )return tmp;
        else return min(f(i,k),f(j,k));
    };
    double ans=0;
    rep(i,n){
        chmin(score[i],f(i,n));
    }
    while(m--){
        lint mn2=INF,k=0;
        rep(i,n){
            if(chmin(mn2,score[i])){
                k=i;
            }
        }
        lint mn=INF,idx=0;
        for(auto j:s){
            if(chmin(mn,f(j,k))){
                idx=j;
            }
        }
        ans+=sqrt(f(k,idx));
        s.emplace(k);
        score[k]=INF;
        rep(i,n){
            if(!s.count(i)){
                chmin(score[i],g(k,idx,i));
            }
        }
    }
    cout<<ans<<endl;
}
accuracy: 0.5
time_ms: 970
memory_kb: 3836
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <complex>
#include <cstdio>
#include <cmath>
#include <utility>
#include <vector>
using namespace std;
using W = double;
using P = complex<W>;
using L = pair<P,P>;
using C = pair<P,W>;
using Poly = vector<P>;
#define X real()
#define Y imag()
const W EPS = (1e-10), pi = acos(-1);
double dot(P a, P b){ return a.X * b.X + a.Y * b.Y;}
W cross(P a, P b){ return a.X * b.Y - a.Y * b.X;}
W ps_dist(P a, L s){
  P sf = s.first, ss = s.second;
  if(dot(ss-sf,a-sf) >= 0 && dot(sf-ss,a-ss) >= 0)
    return abs(cross(sf-ss,a-ss))/abs(sf-ss);
  return min(abs(a-sf), abs(a-ss));
} 

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

int inf = 1e9;

using pdi = pair<double,int>;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;
    cin >> n >> m;
    vector<P> p(n+1);
    double x,y;
    cin >> x >> y;
    p[0] = P(x,y);
    for(int i=1; i<=n; i++){
        cin >> x >> y;
        p[i] = P(x,y);
    }
    bool fst = true;
    vector<bool> used(n+1,false);
    used[0] = true;
    double ans = 0;
    priority_queue<pdi,vector<pdi>,greater<pdi>> que;
    vector<double> dist(n+1);
    for(int i=1; i<=n; i++){
        dist[i] = abs(p[i]-p[0]);
        que.emplace(abs(p[i]-p[0]),i);
    }
    for(int i=0; i<m; i++){
        pdi mn = pdi(inf,inf);
        while(used[que.top().second]) que.pop();
        int id = que.top().second;
        que.pop();
        double res = inf;
        int root;
        for(int j=0; j<=n; j++){
            if(used[j]){
                if(chmin(res,abs(p[id]-p[j]))){
                    root = j;
                }
            }
        }
        ans += res;
        used[id] = true;
        L line = L(p[id],p[root]);
        for(int j=0; j<=n; j++){
            if(used[j]) continue;
            if(chmin(dist[j],abs(p[j]-p[id]))){
                que.emplace(abs(p[j]-p[id]),j);
            }
            if(chmin(dist[j],ps_dist(p[j],line))){
                que.emplace(ps_dist(p[j],line),j);
            }
        }
    }
    cout << fixed << setprecision(10) << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 740
memory_kb: 36056
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <complex>
#include <cstdio>
#include <cmath>
#include <utility>
#include <vector>
using namespace std;
using W = double;
using P = complex<W>;
using L = pair<P,P>;
using C = pair<P,W>;
using Poly = vector<P>;
#define X real()
#define Y imag()
const W EPS = (1e-10), pi = acos(-1);
double dot(P a, P b){ return a.X * b.X + a.Y * b.Y;}
W cross(P a, P b){ return a.X * b.Y - a.Y * b.X;}
W ps_dist(P a, L s){
  P sf = s.first, ss = s.second;
  if(dot(ss-sf,a-sf) >= 0 && dot(sf-ss,a-ss) >= 0)
    return abs(cross(sf-ss,a-ss))/abs(sf-ss);
  return min(abs(a-sf), abs(a-ss));
} 

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;
    cin >> n >> m;
    P ori;
    double x,y;
    cin >> x >> y;
    ori = P(x,y);
    vector<P> p;
    for(int i=0; i<n; i++){
        cin >> x >> y;
        p.emplace_back(x,y);
        // cout << p[i] << endl;
    }
    vector<pair<double,int>> dist(n);
    pair<W,int> mn = make_pair(100000000,100000000);
    for(int i=0; i<n; i++){
        dist[i].first = abs(ori-p[i]);
        dist[i].second = i;
        // cout << ori << endl;
        // cout << p[i] << endl;
        // cout << dist[i].first << endl;
        mn = min(mn,dist[i]);
    }
    vector<bool> used(n,false);
    double ans = 0;
    used[mn.second] = true;
    ans += mn.first;
    for(int i=0; i<n; i++){
        if(used[i]) continue;
        dist[i].first = min(dist[i].first,abs(p[i]-p[mn.second]));
        // 線分
        L sen = make_pair(ori,p[mn.second]);
        dist[i].first = min(dist[i].first,ps_dist(p[i],sen));
    }
    for(int i=0; i<m-1; i++){
        mn = make_pair(1000000000,10000000);
        for(int j=0; j<n; j++){
            if(used[j]) continue;
            mn = min(mn,dist[j]);            
        }
        int id = mn.second;
        pair<double,int> kyo = make_pair(abs(ori-p[id]),-1);        
        for(int j=0; j<n; j++){
            if(used[j]){
                kyo = min(kyo,pair<double,int>(abs(p[j]-p[id]),j));
            }
        }
        used[id] = true;
        ans += kyo.first;
        for(int j=0; j<n; j++){
            if(used[j]) continue;
            dist[j].first = min(dist[j].first,abs(p[j]-p[id]));
            L sen;
            if(kyo.second == -1){
                sen = make_pair(ori,p[id]);
            }else{
                sen = make_pair(p[kyo.second],p[id]); 
            }
            dist[j].first = min(dist[j].first,ps_dist(p[j],sen));
        }
    }
    cout << fixed << setprecision(10) << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 790
memory_kb: 3480
final_rank: 8

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>

using namespace std;
using Real = double;
using Point = complex<Real>;
const Real EPS = 1e-8, PI = acos(-1);

// 実数同士の比較
inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d) {
  return Point(real(p) * d, imag(p) * d);
}

// 入力
istream &operator>>(istream &is, Point &p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

// 出力
ostream &operator<<(ostream &os, Point &p) {
  os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

// 原点を中心として, 点 p を θ 回転すた点を返す
Point rotate(Real theta, const Point &p) {
  return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

// ラジアンを度数に変換
Real radian_to_degree(Real r) {
  return (r * 180.0 / PI);
}

// 度数をラジアンに変換
Real degree_to_radian(Real d) {
  return (d * PI / 180.0);
}

// ∠BAC をラジアンで取得
Real get_angle(const Point &a, const Point &b, const Point &c) {
  const Point v(b - a), w(c - a);
  Real alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real());
  if(alpha > beta) swap(alpha, beta);
  Real theta = (beta - alpha);
  return min(theta, 2 * acos(-1) - theta);
}

// x軸, y軸の順にソート
namespace std {
  bool operator<(const Point &a, const Point &b) {
    return !eq(a.real(), b.real()) ? a.real() < b.real() : a.imag() < b.imag();
  }
}

// 直線
// 2 点を通る直線
// Ax + By = C  
struct Line {
  Point a, b;

  Line() = default;

  Line(Point a, Point b) : a(a), b(b) {}

  Line(Real A, Real B, Real C) // Ax + By = C
  {
    if(eq(A, 0)) a = Point(0, C / B), b = Point(1, C / B);
    else if(eq(B, 0)) b = Point(C / A, 0), b = Point(C / A, 1);
    else a = Point(0, C / B), b = Point(C / A, 0);
  }

  friend ostream &operator<<(ostream &os, Line &p) {
    return os << p.a << " to " << p.b;
  }

  friend istream &operator>>(istream &is, Line &a) {
    return is >> a.a >> a.b;
  }
};

// 線分
// 2 点を結ぶ
struct Segment : Line {
  Segment() = default;
  Segment(Point a, Point b) : Line(a, b) {}
};


// 円
// 中心と半径
struct Circle {
  Point p;
  Real r;

  Circle() = default;

  Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = vector< Point >;
using Polygon = vector< Point >;   // 注意!! 凸多角形は反時計回りに与える.(保証されない場合は面積が負なら reverse をかける)
using Segments = vector< Segment >;
using Lines = vector< Line >;
using Circles = vector< Circle >;

// 外積
Real cross(const Point &a, const Point &b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

// 内積
Real dot(const Point &a, const Point &b) {
  return real(a) * real(b) + imag(a) * imag(b);
}


//          +1
//          
//  +2   a   0   b  -2
//
//          -1
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=jp
int ccw(const Point &a, Point b, Point c) {
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;  // "COUNTER_CLOCKWISE"
  if(cross(b, c) < -EPS) return -1; // "CLOCKWISE"
  if(dot(b, c) < 0) return +2;      // "ONLINE_BACK"
  if(norm(b) < norm(c)) return -2;  // "ONLINE_FRONT"
  return 0;                         // "ON_SEGMENT"
}


// 2 直線が平行か
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) {
  return eq(cross(a.b - a.a, b.b - b.a), 0.0);
}

// 2 直線が垂直か
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) {
  return eq(dot(a.a - a.b, b.a - b.b), 0.0);
}

// 直線 l に 点 p から垂線を下ろして,交わる点を返す
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

// 同じ
// 直線として扱われそう
Point projection(const Segment &l, const Point &p) {
  double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}

// 直線 l に対して, 点 p と線対称な位置にある点を返す.
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) {
  return p + (projection(l, p) - p) * 2.0;
}

// 直線上に点が乗るかどうか
bool intersect(const Line &l, const Point &p) {
  return abs(ccw(l.a, l.b, p)) != 1;
}

// 直線 l と直線 m の交差判定
bool intersect(const Line &l, const Line &m) {
  return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

// 線分上に点があるかどうか
bool intersect(const Segment &s, const Point &p) {
  return ccw(s.a, s.b, p) == 0;
}

// 直線 l と 線分 s の交差判定
bool intersect(const Line &l, const Segment &s) {
  return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

// 点 p と 直線 l との距離
Real distance(const Line &l, const Point &p);

// 円 c と直線 l との交差判定
bool intersect(const Circle &c, const Line &l) {
  return distance(l, c.p) <= c.r + EPS;
}

// 点 p が 円 c 上にあるかどうか
bool intersect(const Circle &c, const Point &p) {
  return abs(abs(p - c.p) - c.r) < EPS;
}


// 線分同士の交差判定
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const Segment &t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 円 c と 線分 l との交差判定
int intersect(const Circle &c, const Segment &l) {
  if(norm(projection(l, c.p) - c.p) - c.r * c.r > EPS) return 0;
  auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
  if(d1 < c.r + EPS && d2 < c.r + EPS) return 0;
  if(d1 < c.r - EPS && d2 > c.r + EPS || d1 > c.r + EPS && d2 < c.r - EPS) return 1;
  const Point h = projection(l, c.p);
  if(dot(l.a - h, l.b - h) < 0) return 2;
  return 0;
}

// 円同士の交差判定
// 4 := 離れている
// 3 := 外接する
// 2 := 交わる
// 1 := 内接する
// 0 := 内包する
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(Circle c1, Circle c2) {
  if(c1.r < c2.r) swap(c1, c2);
  Real d = abs(c1.p - c2.p);
  if(c1.r + c2.r < d) return 4;
  if(eq(c1.r + c2.r, d)) return 3;
  if(c1.r - c2.r < d) return 2;
  if(eq(c1.r - c2.r, d)) return 1;
  return 0;
}

// 点と点の距離
Real distance(const Point &a, const Point &b) {
  return abs(a - b);
}

// 直線と点の距離
Real distance(const Line &l, const Point &p) {
  return abs(p - projection(l, p));
}

// 直線と直線の距離 (もちろん交わってたら 0)
Real distance(const Line &l, const Line &m) {
  return intersect(l, m) ? 0 : distance(l, m.a);
}

// 線分と点の距離
Real distance(const Segment &s, const Point &p) {
  Point r = projection(s, p);
  if(intersect(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}

// 線分同士の距離
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
  if(intersect(a, b)) return 0;
  return min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

// 直線と線分の距離
Real distance(const Line &l, const Segment &s) {
  if(intersect(l, s)) return 0;
  return min(distance(l, s.a), distance(l, s.b));
}

// 直線同士の交点を返す (交差することが要請されるのかな (事前にintersect を呼べばいい))
Point crosspoint(const Line &l, const Line &m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}

// 線分同士の交点を返す (交差することが要請されるのかな (事前にintersect を呼べばいい))
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) {
  return crosspoint(Line(l), Line(m));
}


// 円と直線の交点を返す (交差することが要請されるのかな (事前にintersect を呼べばいい))
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
pair< Point, Point > crosspoint(const Circle &c, const Line l) {
  Point pr = projection(l, c.p);
  Point e = (l.b - l.a) / abs(l.b - l.a);
  if(eq(distance(l, c.p), c.r)) return {pr, pr};
  double base = sqrt(c.r * c.r - norm(pr - c.p));
  return {pr - e * base, pr + e * base};
}


// 円と線分の交点を返す (交差することが要請されるのかな (事前にintersect を呼べばいい))
pair< Point, Point > crosspoint(const Circle &c, const Segment &l) {
  Line aa = Line(l.a, l.b);
  if(intersect(c, l) == 2) return crosspoint(c, aa);
  auto ret = crosspoint(c, aa);
  if(dot(l.a - ret.first, l.b - ret.first) < 0) ret.second = ret.first;
  else ret.first = ret.second;
  return ret;
}

// 円同士の交点を返す (交差することが要請されるのかな (事前にintersect を呼べばいい))
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
pair< Point, Point > crosspoint(const Circle &c1, const Circle &c2) {
  Real d = abs(c1.p - c2.p);
  Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
  Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
  Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
  Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
  return {p1, p2};
}

// 点 p から円 C へ接戦を引いた時の、接点を返す
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
pair< Point, Point > tangent(const Circle &c1, const Point &p2) {
  return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// 円と円の共通接線を複数返す
// 0 ~ 4 つの可能性がある
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
Lines tangent(Circle c1, Circle c2) {
  Lines ret;
  if(c1.r < c2.r) swap(c1, c2);
  Real g = norm(c1.p - c2.p);
  if(eq(g, 0)) return ret;
  Point u = (c2.p - c1.p) / sqrt(g);
  Point v = rotate(PI * 0.5, u);
  for(int s : {-1, 1}) {
    Real h = (c1.r + s * c2.r) / sqrt(g);
    if(eq(1 - h * h, 0)) {
      ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
    } else if(1 - h * h > 0) {
      Point uu = u * h, vv = v * sqrt(1 - h * h);
      ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
      ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
    }
  }
  return ret;
}

// 多角形が凸かどうかを判定
// 与えられる多角形は反時計回りなことが要請される
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex(const Polygon &p) {
  int n = (int) p.size();
  for(int i = 0; i < n; i++) {
    if(ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == -1) return false;
  }
  return true;
}

// 凸包に含まれる点上および辺上の頂点からなる多角形を返す.
// 多角形の開始位置は特に指定がない.
// 反時計回りに返されることは保証されていそう
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon &p) {
  int n = (int) p.size(), k = 0;
  if(n <= 2) return p;
  sort(p.begin(), p.end());
  vector< Point > ch(2 * n);
  for(int i = 0; i < n; ch[k++] = p[i++]) {
    while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
    while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
  }
  ch.resize(k - 1);
  return ch;
}

// 多角形 Q と点 p との関係を返す
// 0 := OUT
// 1 := ON
// 2 := IN
// 多角形は反時計回りに渡す
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
enum {
  OUT, ON, IN
};
int contains(const Polygon &Q, const Point &p) {
  bool in = false;
  for(int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if(a.imag() > b.imag()) swap(a, b);
    if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
    if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
  }
  return in ? IN : OUT;
}

// TODO よくわからん
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
void merge_segments(vector< Segment > &segs) {

  auto merge_if_able = [](Segment &s1, const Segment &s2) {
    if(abs(cross(s1.b - s1.a, s2.b - s2.a)) > EPS) return false;
    if(ccw(s1.a, s2.a, s1.b) == 1 || ccw(s1.a, s2.a, s1.b) == -1) return false;
    if(ccw(s1.a, s1.b, s2.a) == -2 || ccw(s2.a, s2.b, s1.a) == -2) return false;
    s1 = Segment(min(s1.a, s2.a), max(s1.b, s2.b));
    return true;
  };

  for(int i = 0; i < segs.size(); i++) {
    if(segs[i].b < segs[i].a) swap(segs[i].a, segs[i].b);
  }
  for(int i = 0; i < segs.size(); i++) {
    for(int j = i + 1; j < segs.size(); j++) {
      if(merge_if_able(segs[i], segs[j])) {
        segs[j--] = segs.back(), segs.pop_back();
      }
    }
  }
}

// TODO よくわからん
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1033
vector< vector< int > > segment_arrangement(vector< Segment > &segs, vector< Point > &ps) {
  vector< vector< int > > g;
  int N = (int) segs.size();
  for(int i = 0; i < N; i++) {
    ps.emplace_back(segs[i].a);
    ps.emplace_back(segs[i].b);
    for(int j = i + 1; j < N; j++) {
      const Point p1 = segs[i].b - segs[i].a;
      const Point p2 = segs[j].b - segs[j].a;
      if(cross(p1, p2) == 0) continue;
      if(intersect(segs[i], segs[j])) {
        ps.emplace_back(crosspoint(segs[i], segs[j]));
      }
    }
  }
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));

  int M = (int) ps.size();
  g.resize(M);
  for(int i = 0; i < N; i++) {
    vector< int > vec;
    for(int j = 0; j < M; j++) {
      if(intersect(segs[i], ps[j])) {
        vec.emplace_back(j);
      }
    }
    for(int j = 1; j < vec.size(); j++) {
      g[vec[j - 1]].push_back(vec[j]);
      g[vec[j]].push_back(vec[j - 1]);
    }
  }
  return (g);
}


// 直線の進行方向の右側を残す
// Polygon は反時計回りに与える
// Line には一応向きがあるわけで
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
Polygon convex_cut(const Polygon &U, Line l) {
  Polygon ret;
  for(int i = 0; i < U.size(); i++) {
    Point now = U[i], nxt = U[(i + 1) % U.size()];
    if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
    if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0) {
      ret.push_back(crosspoint(Line(now, nxt), l));
    }
  }
  return (ret);
}


// 多角形の面積
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
Real area2(const Polygon &p) {
  Real A = 0;
  for(int i = 0; i < p.size(); ++i) {
    A += cross(p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// 多角形と円の共通部分の面積
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_H
Real area2(const Polygon &p, const Circle &c) {
  if(p.size() < 3) return 0.0;
  function< Real(Circle, Point, Point) > cross_area = [&](const Circle &c, const Point &a, const Point &b) {
    Point va = c.p - a, vb = c.p - b;
    Real f = cross(va, vb), ret = 0.0;
    if(eq(f, 0.0)) return ret;
    if(max(abs(va), abs(vb)) < c.r + EPS) return f;
    if(distance(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
    auto u = crosspoint(c, Segment(a, b));
    vector< Point > tot{a, u.first, u.second, b};
    for(int i = 0; i + 1 < tot.size(); i++) {
      ret += cross_area(c, tot[i], tot[i + 1]);
    }
    return ret;
  };
  Real A = 0;
  for(int i = 0; i < p.size(); i++) {
    A += cross_area(c, p[i], p[(i + 1) % p.size()]);
  }
  return A;
}

// 凸多角形 g の直径を求めよ。ただし、凸多角形の直径とはその最遠頂点対間距離のことである.
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
Real convex_diameter(const Polygon &p) {
  int N = (int) p.size();
  int is = 0, js = 0;
  for(int i = 1; i < N; i++) {
    if(p[i].imag() > p[is].imag()) is = i;
    if(p[i].imag() < p[js].imag()) js = i;
  }
  Real maxdis = norm(p[is] - p[js]);

  int maxi, maxj, i, j;
  i = maxi = is;
  j = maxj = js;
  do {
    if(cross(p[(i + 1) % N] - p[i], p[(j + 1) % N] - p[j]) >= 0) {
      j = (j + 1) % N;
    } else {
      i = (i + 1) % N;
    }
    if(norm(p[i] - p[j]) > maxdis) {
      maxdis = norm(p[i] - p[j]);
      maxi = i;
      maxj = j;
    }
  } while(i != is || j != js);
  return sqrt(maxdis);
}


// 平面上の n 個の点について、最も近い２点の距離.
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_5_A
Real closest_pair(Points ps) {
  if(ps.size() <= 1) throw (0);
  sort(begin(ps), end(ps));

  auto compare_y = [&](const Point &a, const Point &b) {
    return imag(a) < imag(b);
  };
  vector< Point > beet(ps.size());
  const Real INF = 1e18;

  function< Real(int, int) > rec = [&](int left, int right) {
    if(right - left <= 1) return INF;
    int mid = (left + right) >> 1;
    auto x = real(ps[mid]);
    auto ret = min(rec(left, mid), rec(mid, right));
    inplace_merge(begin(ps) + left, begin(ps) + mid, begin(ps) + right, compare_y);
    int ptr = 0;
    for(int i = left; i < right; i++) {
      if(abs(real(ps[i]) - x) >= ret) continue;
      for(int j = 0; j < ptr; j++) {
        auto luz = ps[i] - beet[ptr - j - 1];
        if(imag(luz) >= ret) break;
        ret = min(ret, abs(luz));
      }
      beet[ptr++] = ps[i];
    }
    return ret;
  };
  return rec(0, (int) ps.size());
}

int main() {
  int n, m;
  cin >> n >> m;
  double x, y; cin >> x >> y;
  Point p(x, y);

  Points ps(n);

  for (int i = 0; i < n; i++) {
    double px, py; cin >> px >> py;
    ps[i] = Point(px, py);
  }

  // 粘菌は，線分の集合とみなすことができる
  // (距離，頂点)
  using P = pair<double, int>;
  double inf = 1e18;
  vector<double> dist(n, inf);
  priority_queue<P, vector<P>, greater<P>> que;
  int cnt = 0;
  // 始め，すべての頂点間の距離を que へ突っ込む
  for (int i = 0; i < n; i++) {
    double d = distance(p, ps[i]);
    dist[i] = d;
    que.emplace(d, i);
  }

  vector<bool> used(n, false);
  double ans = 0.0;

  while (cnt < m) {
    
    double cost;
    int node;
    tie(cost, node) = que.top();
    que.pop();

    if (dist[node] < cost) continue;

    // 頂点を追加
    cnt++;
    // 確定した頂点の中で，一番近いやつを選ぶ
    int nxtNode = -1;
    double nxtNodeCost = distance(p, ps[node]);;
    for (int i = 0; i < n; i++) {
      if (!used[i]) continue;

      double tmp = distance(ps[i], ps[node]);
      if (nxtNodeCost > tmp) {
        nxtNodeCost = tmp;
        nxtNode = i;
      }
    }

    Point nxtPoint = p;
    if (nxtNode != -1) {
      nxtPoint = ps[nxtNode];
    }

    // 晴れて，線分が決まる
    // ps[node] と nxtPoint
    ans += distance(ps[node], nxtPoint);

    // node を確定させる
    used[node] = true;
    // cerr << "node = " << node + 1 << ", nxtNode = " << nxtNode << endl;

    // まだ確定していない頂点と，この新しい線分の距離を計算して push
    Segment sg(ps[node], nxtPoint);
    for (int i = 0; i < n; i++) {
      if (used[i]) continue;
      double tmp = distance(sg, ps[i]);
      // cerr << "to " << i + 1 << " " << tmp << endl;
      if (dist[i] <= tmp) continue;
      dist[i] = tmp;
      que.emplace(tmp, i);
    }
  }

  // cout << ans << endl;
  printf("%.10f\n", ans);
  return 0;
}
accuracy: 1
time_ms: 950
memory_kb: 35956
final_rank: 17

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
double distanceLP(const L &l, const P &p) {
    return abs(cross(l[1]-l[0], p-l[0])) /abs(l[1]-l[0]);
}
double distanceSP(const L &s, const P &p) {
    if(dot(s[1]-s[0], p-s[0]) < EPS) return abs(p-s[0]);
    if(dot(s[0]-s[1], p-s[1]) < EPS) return abs(p-s[1]);
    return distanceLP(s, p);
}

int main(){
    int n,m,sx,sy;
    cin >> n >> m >> sx >> sy;
    VP p(n+1);
    p[0] = P(sx, sy);
    for(int i=1; i<n+1; i++){
        int x,y;
        cin >> x >> y;
        p[i] = P(x, y);
    }

    vector<double> dist(n+1, INF);
    for(int i=1; i<=n; i++){
        dist[i] = abs(p[i] -p[0]);
    }
    double ans = 0;
    for(int rep=0; rep<m; rep++){
        double minval = INF;
        int newidx = -1;
        for(int i=0; i<n+1; i++){
            if(dist[i] +EPS < minval){
                minval = dist[i];
                newidx = i;
            }
        }
        int nearidx = -1;
        minval = INF;
        for(int i=0; i<n+1; i++){
            if(dist[i] == INF and abs(p[newidx]-p[i]) +EPS < minval){
                nearidx = i;
                minval = abs(p[newidx]-p[i]);
            }
        }
        ans += abs(p[newidx] -p[nearidx]);
        dist[newidx] = INF;
        for(int i=0; i<n+1; i++){
            if(dist[i] == INF) continue;
            dist[i] = min(dist[i], distanceSP(L(p[newidx], p[nearidx]), p[i]));
        }
    }
    cout << fixed << setprecision(10);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 580
memory_kb: 3420
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;

double eps = 1e-6;

signed main(){
    ios::sync_with_stdio(false);
	cin.tie(0);
    cout << fixed << setprecision(20);

    int n,m;
    cin>>n>>m;
    double a[n+1],b[n+1];
    cin>>a[0] >> b[0];
    for(int i=1;i<=n;i++){
        cin>>a[i]>>b[i];
    }
    double ans = 0;
    bool used[n+1]={};
    used[0] =1;
    double dist[n+1]={};
    for(int i=1;i<=n;i++){
        dist[i] = sqrt((a[0]-a[i])*(a[0]-a[i]) + (b[0]-b[i])*(b[0]-b[i]));
    }
    while(m){
        double d=1e13;
        int f=-1;
        for(int i=1;i<=n;i++){
            if(used[i]) continue;
            if(d > eps + dist[i]){
                d = dist[i];
                f = i;
            }
        }
        double x1 = a[f],y2 = b[f];
        d = 1e13;
        int g = 0;
        for(int i=0;i<=n;i++){
            if(!used[i]) continue;
            double ret = (x1-a[i]) * (x1-a[i]) + (y2-b[i])*(y2-b[i]);
            ret = sqrt(ret);
            if(ret+eps < d){
                d = ret;
                g = i;
            }
        }
        ans += d;
        used[f]=1;
        m--;
        //cerr << "a "<<f << " " << g << endl;
        
        for(int i=1;i<=n;i++){
            if(used[i]) continue;
            double ret = 1e14;
            double x1=a[g],y1=b[g],x2=a[f],y2=b[f];
            d = 1e15;
            if(x1==x2){
                if(b[i]>=min(y1,y2) && b[i] <=max(y1,y2)){
                    double ret = abs(a[i]-x1);
                    if(d > ret+eps){
                        d = ret;
                    }
                }
                else{
                    ret = (x1-a[i]) * (x1-a[i]) + (y1-b[i]) * (y1-b[i]);
                    ret = min(ret, (x2-a[i])*(x2-a[i]) + (y2-b[i]) * (y2-b[i]));
                    ret = sqrt(ret);
                    if(ret+eps < d){
                        d = ret;
                    }
                }
            }
            else{
                ret = (x1-a[i]) * (x1-a[i]) + (y1-b[i]) * (y1-b[i]);
                ret = min(ret, (x2-a[i])*(x2-a[i]) + (y2-b[i]) * (y2-b[i]));
                ret = sqrt(ret);
                double k1 = x1*y2 - x2*y1;
                double k2 = a[i] * x1 - a[i]*x2 + y1*b[i] - y2*b[i];
                k2 *= (x1 - x2);
                k1 *= (y1 - y2);
                double K = k2 - k1;
                double c = K / ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
                if(c>=min(x1,x2) && c <= max(x1,x2)){
                    double d = (y1-y2) / (x1-x2) * c + (x1*y2 - x2*y1)/(x1-x2);
                    ret = (c-a[i]) * (c-a[i]) + (d-b[i]) * (d-b[i]);
                    ret = sqrt(ret);
                }
                if(ret+eps < d){
                    d = ret;
                }
            }
            dist[i] = min(dist[i],d);
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 300
memory_kb: 3400
final_rank: 3

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

/***** 基本的準備 *****/

// xy平面上の点(ベクトル)を表現するには、complex型を利用するとよい
typedef complex<double> P;

// 辺の表現 (座標を2つ pair でもつ)
typedef pair<P, P> L;

// 円の表現 (座標 P と 半径 d で表現する)
typedef pair<P, double> C;

// 成分を取り出すのを簡単にする
#define X real()
#define Y imag()

// 誤差(epsilon)の定義
#define EPS (1e-10)

// 2つの要素が等しいかどうか
#define EQ(a,b) (abs((a) - (b)) < EPS)

// 2つのベクトルが等しいかどうか
#define EQV(a,b) ( EQ((a).X, (b).X) && EQ((a).Y, (b).Y) )

// m は n より大きい(以上)かどうか
#define LE(n, m) ((n) < (m) + EPS)
#define LEQ(n, m) ((n) <= (m) + EPS)

// m は n より小さい(以下)かどうか
#define GE(n, m) ((n) + EPS > (m))
#define GEQ(n, m) ((n) + EPS >= (m))

// 2つのベクトルの内積を求める
double dot(P a, P b) {
    return (a.X * b.X + a.Y * b.Y);
}

// 2つのベクトルの外積を求める
double cross(P a, P b) {
    return (a.X * b.Y - a.Y * b.X);
}

// ccw (c が直線(線分) ab に対してどのような位置関係か？)
// Verified: AOJ CGL_1_C: Counter-Clockwise
// +1 ... a → b で半時計方向に折れて b → c (COUNTER_CLOCKWISE)
// -1 ... a → b で時計方向に折れて b → c (CLOCKWISE)
// +2 ... c, a, b がこの順で同一直線状にある場合 (ONLINE_BACK)
// -2 ... a, b, c がこの順で同一直線状にある場合 ( or a == b ) (ONLINE_FRONT)
//  0 ... c が線分 ab 上にある場合 (点 a, b 上を含む) (ON_SEGMENT)
int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if( cross(b,c) > EPS ) return +1;
    if( cross(b,c) < -EPS ) return -1;
    if( dot(b,c) < 0 ) return +2;
    if( norm(b) < norm(c) ) return -2;
    return 0;
}

// 点 a1, a2 を端点とする線分と点 b との距離
double dist_sp(P a1, P a2, P b) {
    if( dot(a2-a1, b-a1) < EPS ) return abs(b - a1);
    if( dot(a1-a2, b-a2) < EPS ) return abs(b - a2);
    return abs( cross(a2-a1, b-a1) ) / abs(a2 - a1);
}

int main() {
    int N, M; cin >> N >> M;
    vector<P> points(N+1);
    for(int i=0; i<N+1; i++) {
        int x, y; cin >> x >> y;
        points[i] = P(x, y);
    }

    vector<bool> selected(N+1, false);
    selected[0] = true;
    vector<double> dist(N+1, INF), pdist(N+1, INF), best(N+1, -1);
    for(int i=1; i<=N; i++) {
        double x = points[0].real() - points[i].real();
        double y = points[0].imag() - points[i].imag();
        dist[i] = sqrt(x*x + y*y);
        pdist[i] = dist[i];
        best[i] = 0;
    }

    double ans = 0;
    for(int i=0; i<M; i++) {
        double min_val = INF; int argmin = -1;
        for(int k=1; k<=N; k++) {
            if(selected[k]) continue;
            // fprintf(stderr, "k = %d, dist = %.12f\n", k, dist[k]);
            if(min_val > dist[k]) {
                min_val = dist[k];
                argmin = k;
            }
        }

        ans += pdist[argmin];
        selected[argmin] = true;

        // argmin と best[argmin] で辺ができる
        // 辺との距離
        int u = argmin, v = best[argmin];
        // fprintf(stderr, "u = %d, v = %d\n", u, v);
        for(int k=0; k<=N; k++) {
            double cost = dist_sp(points[u], points[v], points[k]);
            if(dist[k] > cost) {
                dist[k] = cost;
            }
        }

        // 頂点との距離
        // 誰とつなぐのが最も近いかも更新
        for(int k=0; k<=N; k++) {
            double x = points[argmin].real() - points[k].real();
            double y = points[argmin].imag() - points[k].imag();

            double cost = sqrt(x*x + y*y);
            dist[k] = min(dist[k], cost);

            if(pdist[k] > cost) {
                pdist[k] = cost;
                best[k] = argmin;
            }
        }
    }
    printf("%.12f\n", ans);
    return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 3404
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <tuple>
#include <bitset>
#include <memory>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <numeric>
#include <climits>
#include <cfloat>
struct Vector {
	int x, y;
	int cross(const Vector that) const { return x * that.y - y * that.x; }
	int dot(const Vector that) const { return x * that.x + y * that.y; }
};
struct Point {
	int x, y;
	double distance(const Point that) const {
		return std::sqrt((x - that.x) * (x - that.x) + (y - that.y) * (y - that.y));
	}
	Vector operator-(const Point& that) const {
		return Vector{ x - that.x, y - that.y };
	}
};
struct Edge {
	Point from, to;
	bool has_catheti(const Point& that) const {
		return (to - from).dot(that - from) >= 0 && (from - to).dot(that - to) >= 0;
	}
	double catheti_length(const Point& that) const {
		return std::abs((to.y - from.y) * that.x - (to.x - from.x) * that.y + to.x * from.y - to.y * from.x) / std::sqrt((to.y - from.y) * (to.y - from.y) + (to.x - from.x) * (to.x - from.x));
	}
	double length() const { return from.distance(to); }
};
int main() {
	int n, m, x, y; std::cin >> n >> m >> x >> y;
	std::vector<Point> points(n + 1); points[0] = Point{ x, y };
	for (auto i = 1; i <= n; ++i) std::cin >> points[i].x >> points[i].y;
	std::vector<double> nearest_distance_to_point(n + 1, DBL_MAX), nearest_distance_to_edge(n + 1, DBL_MAX);
	std::vector<int> nearest_point(n + 1, 0);
	std::vector<int> rest(n + 1, -1); for (auto i = 0; i < n; ++i) rest[i] = i + 1;
	auto comparator = [](const std::pair<int, double>& a, const std::pair<int, double>& b) { return (std::abs(a.second - b.second) < 0.0000000001) ? a.first > b.first : a.second > b.second; };
	std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double>>, decltype(comparator)> queue(comparator);
	for (auto i = 1; i <= n; ++i) {
		nearest_distance_to_point[i] = points[0].distance(points[i]);
		queue.emplace(i, nearest_distance_to_point[i]);
		if (nearest_distance_to_point[0] < nearest_distance_to_point[i]) {
			nearest_distance_to_point[0] = nearest_distance_to_point[i];
			nearest_point[0] = i;
		}
	}
	double result = 0;
	for (auto c = 0; c < m; ++c) {
		while (nearest_point[queue.top().first] == -1) queue.pop();
		auto top = queue.top(); queue.pop();
		auto edge = Edge{ points[top.first], points[nearest_point[top.first]] };
		result += nearest_distance_to_point[top.first];
		nearest_point[top.first] = -1;
		for (auto i = 0; i < n - c - 1; ++i) {
			if (rest[i] == top.first) {
				rest[i] = rest[n - c - 1];
			}
			auto distance = points[top.first].distance(points[rest[i]]);
			if (nearest_distance_to_point[rest[i]] > distance) {
				nearest_distance_to_point[rest[i]] = distance;
				nearest_point[rest[i]] = top.first;
				if (nearest_distance_to_edge[rest[i]] > distance) {
					nearest_distance_to_edge[rest[i]] = distance;
					queue.emplace(rest[i], distance);
				}
			}
			if (edge.has_catheti(points[rest[i]])) {
				auto d = edge.catheti_length(points[rest[i]]);
				if (nearest_distance_to_edge[rest[i]] > d) {
					nearest_distance_to_edge[rest[i]] = d;
					queue.emplace(rest[i], d);
				}
			}
		}
	}
	std::cout << std::setprecision(15) << std::fixed << result << std::endl;
}
accuracy: 1
time_ms: 130
memory_kb: 35880
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int INF = 1e9;
const ll LINF = 1e18;
template<class S,class T> ostream& operator << (ostream& out,const pair<S,T>& o){ out << "(" << o.first << "," << o.second << ")"; return out; }
template<class T> ostream& operator << (ostream& out,const vector<T> V){ for(int i = 0; i < V.size(); i++){ out << V[i]; if(i!=V.size()-1) out << " ";} return out; }
template<class T> ostream& operator << (ostream& out,const vector<vector<T> > Mat){ for(int i = 0; i < Mat.size(); i++) { if(i != 0) out << endl; out << Mat[i];} return out; }
template<class S,class T> ostream& operator << (ostream& out,const map<S,T> mp){ out << "{ "; for(auto it = mp.begin(); it != mp.end(); it++){ out << it->first << ":" << it->second; if(mp.size()-1 != distance(mp.begin(),it)) out << ", "; } out << " }"; return out; }

/*
 <url:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2774>
 問題文============================================================
 =================================================================
 解説=============================================================
 
 prim法の要領で辺を追加するたびに、各頂点への最短距離を更新していけば良い
 ================================================================
 */
typedef double ld;
typedef complex<ld> Point;
const ld eps = 1e-9, pi = acos(-1.0);
namespace std {
    bool operator < (const Point& lhs, const Point& rhs) {
        if (lhs.real() < rhs.real() - eps) return true;
        if (lhs.real() < rhs.real() + eps) return false;
        return lhs.imag() < rhs.imag();
    }
}

class Line {
public:
    Point a, b;
    Line() :a(Point(0, 0)), b(Point(0, 0)) {}
    Line(Point a, Point b) :a(a), b(b) {}
    Point operator[](const int _num) {
        if (_num == 0) return a;
        else if (_num == 1) return b;
        else assert(false);
    }
};

ld dot(Point a, Point b) { return real(conj(a)*b); }
Point proj(Line l, Point p) {
    ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + t * (l.a - l.b);
}
bool isis_sp(Line s, Point p) {
    return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

ld dist_sp(Line s, Point p) {
    Point r = proj(s, p);
    return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

void solve() {
    int N, M, X, Y; cin >> N >> M >> X >> Y;
    vector<int> flag(N+1, 0);
    vector<Point> ps(N+1);
    ps[0] = Point(X, Y); flag[0] = 1;
    for (int i = 1; i <= N; i++) {
        int a, b; cin >> a >> b;
        ps[i] = Point(a, b);
    }
    
    ld ans = 0;
    vector<double> dist(N + 1, LINF);
    for (int i = 0; i <= N; i++) {
        dist[i] = abs(ps[i] - ps[0]);
    }
    for (int i = 0; i < M; i++) {
        ld len = LINF;
        int idx = -1;
        for (int i = 0; i <= N; i++) {
            if (flag[i] == 1) continue;
            if (len > dist[i]) {
                len = dist[i];
                idx = i;
            }
        }
        
        len = LINF;
        int pidx = -1;
        for (int i = 0; i <= N; i++) {
            if (flag[i] == 1) {
                ld d = abs(ps[i] - ps[idx]);
                if (len > d) {
                    len = d;
                    pidx = i;
                }
            }
        }
        ans += abs(ps[idx] - ps[pidx]);
        flag[idx] = 1;
        Line L(ps[idx], ps[pidx]);
        for (int i = 0; i <= N; i++) {
            if (flag[i] == 1) continue;
            dist[i] = min(dist[i], dist_sp(L, ps[i]));
        }
    }
    cout << fixed << setprecision(12) << ans << endl;
}

int main() {
    cin.tie(0); ios_base::sync_with_stdio(false);
    solve();
    return 0;
}
accuracy: 1
time_ms: 1200
memory_kb: 3448
final_rank: 10

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 5001

struct Point{
    double x,y;
};

typedef Point Vector;

struct Line{
    void set(double x1,double y1,double x2,double y2){
        p1.x = x1;
        p1.y = y1;
        p2.x = x2;
        p2.y = y2;
    }
    Point p1,p2;
};

typedef Line Segment;

int N,M;
bool is_nenkin[NUM];
Point point[NUM];
double min_dist[NUM];
int index[NUM];


double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p2,l.p1),calc_minus(p,l.p1))/calc_len(calc_minus(l.p2,l.p1)));
}

double getDistanceSP(Segment s,Point p){
	if(dot(calc_minus(s.p2,s.p1),calc_minus(p,s.p1)) < 0.0)return calc_len(calc_minus(p,s.p1));
	if(dot(calc_minus(s.p1,s.p2),calc_minus(p,s.p2)) < 0.0)return calc_len(calc_minus(p,s.p2));
	return getDistanceLP(s,p);
}


double calc_dist(int from,int to){
	return sqrt((point[from].x-point[to].x)*(point[from].x-point[to].x)+(point[from].y-point[to].y)*(point[from].y-point[to].y));
}


int main(){

	scanf("%d %d %lf %lf",&N,&M,&point[0].x,&point[0].y);

	is_nenkin[0] = true;
	min_dist[0] = 0;

	for(int i = 1; i <= N; i++){
		is_nenkin[i] = false;
		min_dist[i] = DBL_MAX;
		scanf("%lf %lf",&point[i].x,&point[i].y);
	}

	int next;
	double minimum = DBL_MAX,tmp_dist;

	for(int i = 1; i <= N; i++){
		tmp_dist = calc_dist(0,i);
		if(minimum > tmp_dist){
			minimum = tmp_dist;
			next = i;
		}
	}

	vector<int> Group;

	double ans = minimum;
	is_nenkin[next] = true;
	Group.push_back(0);
	Group.push_back(next);

	Line first_line;
	first_line.set(point[0].x,point[0].y,point[next].x,point[next].y);

	minimum = DBL_MAX;
	for(int i = 1; i <= N; i++){
		if(is_nenkin[i])continue;
		tmp_dist = getDistanceSP(first_line,point[i]);
		min_dist[i] = tmp_dist;
	}

	int count = 1,from;

	while(count < M){

		minimum = DBL_MAX;
		for(int i = 1; i <= N; i++){
			if(is_nenkin[i])continue;
			if(minimum > min_dist[i]){
				minimum = min_dist[i];
				next = i;
			}
		}

		minimum = DBL_MAX;
		for(int i = 0; i < Group.size(); i++){
			tmp_dist = calc_dist(next,Group[i]);
			if(minimum > tmp_dist){
				minimum = tmp_dist;
				from = Group[i];
			}else if(fabs(minimum-tmp_dist) < EPS){
				if(from > Group[i]){
					from = Group[i];
				}
			}
		}

		ans += minimum;
		count++;
		if(count == M)break;

		is_nenkin[next] = true;
		Group.push_back(next);
		Line new_line;
		new_line.set(point[from].x,point[from].y,point[next].x,point[next].y);

		for(int i = 1; i <= N; i++){
			if(is_nenkin[i])continue;

			min_dist[i] = min(min_dist[i],getDistanceSP(new_line,point[i]));
		}
	}

	printf("%.10lf\n",ans);

	return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 3404
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

using P = pair<int,int>;

long dist(P &a, P &b){
  long x=a.fi-b.fi;
  long y=a.se-b.se;
  return x*x+y*y;
}

double dist(P &a, P &b, P &c){
  long ipa = (b.fi-a.fi)*(c.fi-a.fi) + (b.se-a.se)*(c.se-a.se);
  long ipb = (a.fi-b.fi)*(c.fi-b.fi) + (a.se-b.se)*(c.se-b.se);
  if(ipa<=0 || ipb<=0) return min(dist(a,c), dist(b,c));
  else {
    long outacab = (c.fi-a.fi)*(b.se-a.se) - (c.se-a.se)*(b.fi-a.fi);
    return (double)outacab*outacab / dist(a,b);
  }
}

int main(){
  int n,m;
  cin>>n>>m;
  vector<P> p(n+1);
  cin>>p[0].fi>>p[0].se;
  rep(i,1,n+1) cin>>p[i].fi>>p[i].se;

  n++;

  vector<bool> used(n, false);
  used[0]=true;
  vector<double> dd(n); // dist^2
  rep(i,n) dd[i] = dist(p[0],p[i]);
  dd[0] = INF;

  double ans = 0;
  rep(_,m){
    int cand = 0;
    rep(j,1,n) if(!used[j] && dd[cand] > dd[j]) cand = j;

    double add = INF;
    int from = 0;
    rep(j,n) if(used[j] && dist(p[cand], p[j]) < add) from=j, add = dist(p[cand], p[j]);

    ans += sqrt(add);//dbg(add,from);
    used[cand] = true;

    rep(j,n) if(!used[j]) dd[j] = min<double>(dd[j], dist(p[cand], p[from], p[j]));
  }

  printf("%.10f\n", ans);

  return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 3248
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define _rep(i,n) _repl(i,0,n)
#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)
#define mp(a,b) make_pair((a),(b))
#define pb(a) push_back((a))
#define all(x) (x).begin(),(x).end()
#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))
#define fi first
#define se second
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
void _dbg(string){cout<<endl;}
template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}
template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

#define INF 1120000000

using P = pair<int,int>;

long dist(P &a, P &b){
  long x=a.fi-b.fi;
  long y=a.se-b.se;
  return x*x+y*y;
}

double dist(P &a, P &b, P &c){
  long ipa = (b.fi-a.fi)*(c.fi-a.fi) + (b.se-a.se)*(c.se-a.se);
  long ipb = (a.fi-b.fi)*(c.fi-b.fi) + (a.se-b.se)*(c.se-b.se);
  if(ipa<=0 || ipb<=0) return min(dist(a,c), dist(b,c));
  else {
    long outacab = (c.fi-a.fi)*(b.se-a.se) - (c.se-a.se)*(b.fi-a.fi);
    return (double)outacab*outacab / dist(a,b);
  }
}

int main(){
  int n,m;
  cin>>n>>m;
  vector<P> p(n+1);
  cin>>p[0].fi>>p[0].se;
  rep(i,1,n+1) cin>>p[i].fi>>p[i].se;

  n++;

  vector<bool> used(n, false);
  used[0]=true;
  vector<int> dd(n); // dist^2
  rep(i,n) dd[i] = dist(p[0],p[i]);
  dd[0] = INF;

  double ans = 0;
  rep(_,m){
    int cand = 0;
    rep(j,1,n) if(!used[j] && dd[cand] > dd[j]) cand = j;

    double add = INF;
    int from = 0;
    rep(j,n) if(used[j] && dist(p[cand], p[j]) < add) from=j, add = dist(p[cand], p[j]);

    ans += sqrt(add);//dbg(add,from);
    used[cand] = true;

    rep(j,n) if(!used[j]) dd[j] = min<int>(dd[j], dist(p[cand], p[from], p[j]));
  }

  printf("%.10f\n", ans);

  return 0;
}
accuracy: 0.5
time_ms: 260
memory_kb: 3212
final_rank: 18