Problem:
Problem I: Explosion

Problem

大魔王めぐみんは地上に生存する$N$人の勇者を倒そうと考えている。

めぐみんは$M$回まで爆発魔法を唱えることができる。

爆発魔法は任意の座標を中心に半径$r$以内に存在している勇者を消滅させる魔法である。

勇者はとても痩せているため大きさは考慮しなくてよい。

$M$回の爆発魔法は全て同じ大きさの半径で唱えるものとする。

勇者を全滅させるのに必要最小限の半径の魔法を使うことにした。

爆発魔法の半径の大きさを最小化せよ。

Input

$N$ $M$
$x_1$ $y_1$
...
$x_N$ $y_N$

入力は以下の形式で与えられる。

1行目に 勇者の数 $N$ 、唱える爆発の数 $M$ が整数で与えられる。

2行目以降にそれぞれの勇者$i$の座標 $x_i$ $,$ $y_i$ が整数で与えられる。

Constraints

入力は以下の条件を満たす。

$1 \leq M \leq N \leq 14$

$0 \leq x_i $,$ y_i \leq 10^5$

Output

爆発魔法の半径の最小値を実数で出力せよ。

$10^{-3}$を超える絶対誤差を含んではならない。

Sample Input 1

5 2
0 0
5 5
10 10
100 100
200 200

Sample Output 1

70.710678118755

Sample Input 2

10 5
321 675
4312 6534
312 532
412 6543
21 43
654 321
543 0
32 5
41 76
5 1

Sample Output 2

169.824909833728

Sample Input 3

14 3
312 342
4893 432
321 4
389 4
23 543
0 0
1 1
2 2
432 12
435 32
1 5
2 10
100 100
20 50

Sample Output 3

218.087711712613

Sample Input 4

5 2
0 0
0 0
0 0
0 0
0 0

Sample Output 4

0.000000000001

Solution in C++11 (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <unordered_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 {
	double x, y;
	double length() const { return std::sqrt(x * x + y * y); }
	double dot(const Vector& that) const { return x * that.x + y * that.y; }
	double cross(const Vector& that) const { return x * that.y - y * that.x; }
	Vector rotate90() const { return Vector{ -y, x }; }
	Vector flip180() const { return Vector{ -x, -y }; }
};
Vector operator*(const Vector& vec, const double scala) { return Vector{ vec.x * scala, vec.y * scala }; }
Vector operator*(const double scala, const Vector& vec) { return Vector{ vec.x * scala, vec.y * scala }; }
struct Coordinate {
	double x, y;
	double distance_from(const Coordinate& that) const { return (*this - that).length(); }
	Coordinate mid_point(const Coordinate& that) const { return Coordinate{ (x + that.x) / 2, (y + that.y) / 2 }; }
	Vector operator-(const Coordinate& that) const { return Vector{ x - that.x, y - that.y }; }
};
Coordinate operator+(const Vector& vec, const Coordinate& coordinate) { return Coordinate{ vec.x + coordinate.x, vec.y + coordinate.y }; }
Coordinate operator+(const Coordinate& coordinate, const Vector& vec) { return Coordinate{ vec.x + coordinate.x, vec.y + coordinate.y }; }
constexpr double EPS = 0.000000001;
int remove_all(const std::vector<Coordinate>& bravers, int state, const double radius, const Coordinate center) {
	for (auto i = 0; i < bravers.size(); ++i) if ((state & (1 << i)) != 0) {
		if (bravers[i].distance_from(center) <= radius + EPS) {
			state ^= 1 << i;
		}
	}
	return state;
}
bool can_defeat(const std::vector<Coordinate>& bravers, const int state, const int rest, const double radius, std::vector<std::vector<int>> &memo) {
	if (state == 0) return true;
	if (rest == 0) return false;
	if (memo[rest][state] >= 0) return memo[rest][state] == 1;
	memo[rest][state] = 0;
	for (auto i = 0; i < bravers.size(); ++i) if ((state & (1 << i)) != 0) {
		if (can_defeat(bravers, remove_all(bravers, state, radius, bravers[i]), rest - 1, radius, memo)) {
			memo[rest][state] = 1;
			return true;
		}
		for (auto j = 0; j < i; ++j) if ((state & (1 << j)) != 0 && bravers[i].distance_from(bravers[j]) <= radius * 2 + EPS && EPS < bravers[i].distance_from(bravers[j])) {
			auto mid = bravers[i].mid_point(bravers[j]);
			auto vec = bravers[i] - bravers[j];
			auto catheti = vec.rotate90() * std::sqrt(radius * radius - vec.length() * vec.length() / 4) * (1 / vec.length());
			if (can_defeat(bravers, remove_all(bravers, state, radius, mid + catheti), rest - 1, radius, memo) || can_defeat(bravers, remove_all(bravers, state, radius, mid + catheti.flip180()), rest - 1, radius, memo)) {
				memo[rest][state] = 1;
				return true;
			}
		}
	}
	return false;
}
int main() {
	int n, m; std::cin >> n >> m;
	std::vector<Coordinate> bravers(n); for (auto& braver : bravers) std::cin >> braver.x >> braver.y;
	std::vector<std::vector<int>> memo(m + 1, std::vector<int>(1 << n, -1));
	double min = 0.0;
	double max = 150000;
	while (min + 0.000001 < max) {
		auto mid = (min + max) / 2;
		for (auto& vec : memo) std::fill(vec.begin(), vec.end(), -1);
		if (can_defeat(bravers, (1 << n) - 1, m, mid, memo)) max = mid;
		else min = mid;
	}
	std::cout << std::setprecision(10) << std::fixed << max << '\n';
}