QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#65569 | #3858. Systematic salesman | UBB_Zalau00# | ML | 0ms | 0kb | C++14 | 4.8kb | 2022-12-01 20:51:27 | 2022-12-01 20:51:28 |
Judging History
answer
#include <bits/stdc++.h>
#ifdef LOCAL_DEFINE
#include <dbg.h>
#else
#define dbg(...)
#endif
using namespace std;
struct Point {
int x, y;
int id;
double Dist(const Point &other) const {
return sqrt(1LL * (x - other.x) * (x - other.x) + 1LL * (y - other.y) * (y - other.y));
}
};
bool CompByX(const Point &a, const Point &b) {
return a.x < b.x;
}
bool CompByY(const Point &a, const Point &b) {
return a.y < b.y;
}
typedef bool (*Comp)(const Point &a, const Point &b);
Comp GetComp(int type) {
return type == 0 ? CompByX : CompByY;
}
const int N = 1001;
double dp[N][N];
double dp2[N][N];
double dist[N][N];
int recon[N][N];
int recon2[N][N];
Point pts[N];
int Mid(int l, int r) {
return (l + r + 1) / 2;
}
void Sort(int l, int r, int type) {
if (l == r) return;
sort(pts + l, pts + r + 1, GetComp(type));
int m = Mid(l, r);
Sort(l, m - 1, 1 ^ type);
Sort(m, r, 1 ^ type);
}
template<typename T>
bool Min(T &a, const T &b) { return a < b ? false : (a = b, true); }
bool known[N][N];
vector<int> ans[N][N];
void Divide(int l, int r) {
if (l == r) {
dp[l][r] = 0;
return;
}
int m = Mid(l, r);
Divide(l, m - 1);
Divide(m, r);
if (l + 1 == r) {
dp[l][r] = dp[r][l] = dist[l][r];
known[l][r] = known[r][l] = true;
ans[l][r] = {l, r};
ans[r][l] = {r, l};
return;
}
if (l + 2 == r) {
dp[l][r] = dist[l][l + 1] + dp[l + 1][r];
dp[l][l + 1] = dist[l][r] + dp[r][l + 1];
dp[r][l] = dp[l][r];
dp[l + 1][l] = dp[l][l + 1];
known[l][r] = known[r][l] = true;
known[l][l + 1] = known[l + 1][l] = true;
ans[l][r] = {l, l + 1, r};
ans[l][l + 1] = {l, r, l + 1};
ans[r][l] = {r, l + 1, l};
ans[l + 1][l] = {l + 1, r, l};
return;
}
int lim = Mid(l, m - 1);
for (int u = l; u < m; ++u) {
for (int j = m; j <= r; ++j) {
if (u < lim)
for (int i = lim; i <= m - 1; ++i) {
if (Min(dp2[u][j], dp[u][i] + dist[i][j])) {
recon2[u][j] = i;
}
}
else
for (int i = l; i < lim; ++i) {
if (Min(dp2[u][j], dp[u][i] + dist[i][j])) {
recon2[u][j] = i;
}
}
}
}
lim = Mid(m, r);
for (int u = l; u < m; ++u) {
for (int v = m; v <= r; ++v) {
if (v < lim)
for (int j = lim; j <= r; ++j) {
if (Min(dp[u][v], dp2[u][j] + dp[j][v])) {
recon[u][v] = j;
}
}
else
for (int j = m; j < lim; ++j) {
if (Min(dp[u][v], dp2[u][j] + dp[j][v])) {
recon[u][v] = j;
}
}
dp[v][u] = dp[u][v];
recon[v][u] = recon[u][v];
}
}
}
const double EPS = 1e-6;
bool Eq(double a, double b) {
return fabs(a - b) <= EPS;
}
void Reconstr(int l, int r) {
dbg("Recon", l, r);
if (l == r) {
cout << pts[l].id << ' ';
return;
}
if (known[l][r]) {
for (int x : ans[l][r]) cout << pts[x].id << ' ';
return;
if (l + 1 == r) {
cout << pts[l].id << ' ' << pts[r].id << ' ';
return;
}
if (r + 1 == l) {
cout << pts[r].id << ' ' << pts[l].id << ' ';
return;
}
if (l + 2 == r) {
if (Eq(dist[l][l + 1] + dist[l + 1][r], dp[l][r])) {
cout << pts[l].id << ' ' << pts[l + 1].id << ' ' << pts[r].id << ' ';
} else {
cout << pts[l].id << ' ' << pts[r].id << ' ' << pts[l + 1].id << ' ';
}
return;
}
if (r + 2 == l) {
if (Eq(dist[r][r + 1] + dist[r + 1][l], dp[r][l])) {
cout << pts[r].id << ' ' << pts[r + 1].id << ' ' << pts[l].id << ' ';
} else {
cout << pts[r].id << ' ' << pts[l].id << ' ' << pts[r + 1].id << ' ';
}
return;
}
}
int r2 = recon[l][r];
int r1 = recon2[l][r2];
Reconstr(l, r1);
Reconstr(r2, r);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n; cin >> n;
for (int i = 0; i < n; ++i) {
cin >> pts[i].x >> pts[i].y;
pts[i].id = i + 1;
}
if (n == 1) {
cout << 0 << endl;
return 0;
}
Sort(0, n - 1, 0);
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
dist[i][j] = dist[j][i] = pts[i].Dist(pts[j]);
dp[i][j] = dp[j][i] = dp2[i][j] = dp2[j][i] = 1e18;
// if (i != j) ans[i][j] = {i, j}, ans[j][i] = {j, i};
// else ans[i][j] = {i};
}
}
Divide(0, n - 1);
int lim = Mid(0, n - 1);
double ans = 1e18;
int start = -1, fin = -1;
for (int i = 0; i < lim; ++i) {
for (int j = lim; j < n; ++j) {
if (Min(ans, dp[i][j])) {
start = i;
fin = j;
}
}
}
cout << fixed << setprecision(10) << ans << endl;
Reconstr(start, fin);
cout << endl;
}
詳細信息
Test #1:
score: 0
Memory Limit Exceeded
input:
8 7 3 2 0 4 5 1 4 8 2 9 9 0 8 6 1
output:
26.3833257716