-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsovler-Farthest-Insertion.cpp
83 lines (68 loc) · 2.3 KB
/
sovler-Farthest-Insertion.cpp
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
// Farthest Insertion法(FI)
// 計算量 : O(n^2)
// 精度保証 : なし
#include<bits/stdc++.h>
#include"posIOFile.hpp"
using namespace std;
vector<int> solve(vector<Position>);
int main(int argc, char *argv[]){
assert(argc >= 3);
string inputFile = argv[1];
string outputFile = argv[2];
vector<Position> points;
readFile(inputFile, points);
vector<int> answer = solve(points);
outFile(outputFile, answer);
}
vector<int> solve(vector<Position> points){
int n = points.size();
vector<int> result;
vector<double> distFromRes(n, 1e9); // 集合resultに含まれる点からの最短距離
vector<bool> useEdge(n,false);
auto addPoint = [&](int ind){
result.push_back(ind);
useEdge[ind] = true;
for(int i = 0; i < n; i++){
if(distFromRes[i] > points[ind].dist(points[i])){
distFromRes[i] = points[ind].dist(points[i]);
}
}
};
result.push_back(0);
useEdge[0] = true;
for(int i = 0; i < n; i++){
if(distFromRes[i] > points[0].dist(points[i])){
distFromRes[i] = points[0].dist(points[i]);
}
}
for(int turn = 0; turn < n - 1; turn++){
double maxDist = 0;
int useInd = -1;
for(int i = 0; i < n; i++){
if(!useEdge[i] && distFromRes[i] > maxDist){
useInd = i;
maxDist = distFromRes[i];
}
}
const auto diffDist = [&](int l, int r, int in)->double {
return points[in].dist(points[l]) + points[in].dist(points[r]) - points[l].dist(points[r]);
};
int insertInd = 0;
double minAddDist = diffDist(result.back(), result[0], useInd);
for(int i = 0; i < result.size() - 1; i++){
if(diffDist(result[i], result[i + 1], useInd) < minAddDist){
minAddDist = diffDist(result[i], result[i + 1], useInd);
insertInd = i + 1;
}
}
result.insert(result.begin() + insertInd, useInd);
useEdge[useInd] = true;
for(int i = 0; i < n; i++){
if(distFromRes[i] > points[useInd].dist(points[i])){
distFromRes[i] = points[useInd].dist(points[i]);
}
}
}
for(int i = 0; i < result.size(); i++) result[i]++;
return result;
}