Loading

2018 ICPC Nanjing D. Country Meow ,最小球覆盖,模拟退火

2018 ICPC Nanjing D. Country Meow ,最小球覆盖,模拟退火

题意

给定\(N\) 个点,求一个点使得到这\(N\)个点中最大距离最小,求出这个距离

\[1\leq N \leq 100,-100000\leq x_i,y_i,z_i \leq 100000 \]

分析

容易想到这是一个最小球覆盖问题,这个问题和最小圆覆盖都可以用模拟退化解决。

每次贪心地靠近最远距离即可。

注意这里更新坐标与之前的模拟退化有点不太一样

代码

struct Point {
    double x, y, z;
};

Point p[105];

double get_dis(Point a, Point b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y) + (a.z - b.z) * (a.z - b.z));
}

const double beginT = 10000, endT = 1e-12, delT = 0.99;
int n;
double ans;

void SA(int times) {
    Point pp;
    pp.x = pp.y = pp.z = 0;
    int s = 0 ;
    ans = 1e18;
    while (times--) {
        for (double T = beginT; T >= endT; T *= delT) {
            for (int i = 1; i <= n; i++)
                if (get_dis(pp, p[i]) > get_dis(pp, p[s])) s = i;
         
            double d = get_dis(p[s], pp);
            ans = min(ans, d);
            pp.x += (p[s].x - pp.x) * T / beginT;
            pp.y += (p[s].y - pp.y) * T / beginT;
            pp.z += (p[s].z - pp.z) * T / beginT;
        }
    }
}

int main() {
    n = readint();
    for (int i = 1; i <= n; i++) scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].z);
    SA(10);
    printf("%.8f", ans);
}
posted @ 2020-09-06 23:07  MQFLLY  阅读(152)  评论(0编辑  收藏  举报