刚学模拟退火,觉得写的挺对的( 降温什么的也都调过了,不知道咋就wa了,也没数据
#include <cmath>
#include <iostream>
using namespace std;
#define DEBUG(A) cout << A << endl
#define N 10100
#define eps 1e-15
#define down 0.9999
struct point {
double x, y;
};
point p[N];
int n;
double dis(point p1, point p2) {
return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
double ans;
point ansp;
void sa() {
for (double T = 3000; T > eps; T *= down) {
point np;
np.x = (rand() * 2 - RAND_MAX) * T;
np.y = (rand() * 2 - RAND_MAX) * T;
double nans = 0;
for (int i = 1; i <= n; i++) {
nans += dis(np, p[i]);
}
double dans = nans - ans;
// DEBUG(dans);
if (dans < eps) {
ans = nans;
ansp = np;
} else {
if (exp(-dans / T) * RAND_MAX > rand()) {
ans = nans;
ansp = np;
}
}
}
}
signed main() {
/*code here*/
int T;
cin >> T;
while (T--) {
cin >> n;
ans = 0;
ansp.x = 0;
ansp.y = 0;
for (int i = 1; i <= n; i++) {
cin >> p[i].x >> p[i].y;
ansp.x += p[i].x;
ansp.y += p[i].y;
}
ansp.x /= n;
ansp.y /= n;
for (int i = 1; i <= n; i++) {
ans += dis(ansp, p[i]);
}
sa();
sa();
sa();
sa();
printf("%0.0lf\n", ans);
if (T) {
printf("\n");
}
}
return 0;
}