1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
using ld = long double;
ld hungarian(const vector<vector<ld>>& a) {
int n = (int)a.size() - 1;
const ld INF = 1e100L;
vector<ld> u(n + 1, 0), v(n + 1, 0), minv(n + 1);
vector<int> p(n + 1), way(n + 1);
for (int i = 1; i <= n; ++i) {
p[0] = i;
int j0 = 0;
vector<char> used(n + 1, false);
fill(minv.begin(), minv.end(), INF);
do {
used[j0] = true;
int i0 = p[j0], j1 = 0;
ld delta = INF;
for (int j = 1; j <= n; ++j) if (!used[j]) {
ld cur = a[i0][j] - u[i0] - v[j];
if (cur < minv[j]) {
minv[j] = cur;
way[j] = j0;
}
if (minv[j] < delta) {
delta = minv[j];
j1 = j;
}
}
for (int j = 0; j <= n; ++j) {
if (used[j]) {
u[p[j]] += delta;
v[j] -= delta;
} else {
minv[j] -= delta;
}
}
j0 = j1;
} while (p[j0] != 0);
do {
int j1 = way[j0];
p[j0] = p[j1];
j0 = j1;
} while (j0 != 0);
}
ld value = 0;
for (int j = 1; j <= n; ++j) value += a[p[j]][j];
return value;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
if (!(cin >> N)) return 0;
vector<pair<ld, ld>> pt(N + 1);
for (int i = 1; i <= N; ++i) {
ld x, y; cin >> x >> y;
pt[i] = {x, y};
}
vector<vector<ld>> cost(N + 1, vector<ld>(N + 1, 0));
for (int i = 1; i <= N; ++i) {
for (int j = 1; j <= N; ++j) {
ld dx = pt[i].first + pt[j].first; // xi - (-xj)
ld dy = pt[i].second - pt[j].second; // yi - yj
cost[i][j] = sqrtl(dx * dx + dy * dy);
}
}
ld match_cost = hungarian(cost);
ld answer = match_cost / 2.0L;
cout.setf(std::ios::fixed);
cout << setprecision(3) << (double)answer << '\n';
return 0;
}
|