最小球覆盖:用半径最小的球去覆盖所有点。
纯粹的退火算法,是搞不定的,精度不够,不然就会TLE,根本跑不出答案来。
任取一点为球心,然后一点点靠近最远点。其实这才是最主要的。
因为:4个点确定一个球,也就是说,这个球,会慢慢稳定,每次用一个点到最远的点的距离去靠近,怎么靠近,玄学距离 。
再在这个基础上乘以 t ,模拟退火温度。这样靠近速度增加。并且不用判断是否较以前是否更优才转移,因为他是必须转移过去。至少你不可能是最长边的端点的,而且他会随着温度逐渐稳定。
#include#include #include using namespace std;const int maxn = 35;struct Node { double x,y,z;}nodes[maxn];int n;double dist(Node a,Node 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) );}double calc(Node z) { double ret = 0; for(int i = 0; i < n; i++) ret = max(ret,dist(z,nodes[i])); return ret;}int dx[6] = { 0,0,0,0,1,-1};int dy[6] = { 0,0,-1,1,0,0};int dz[6] = {-1,1,0,0,0,0};int main(){ //freopen("in.txt","r",stdin); while(scanf("%d",&n),n) { for(int i = 0; i < n; i++) scanf("%lf%lf%lf",&nodes[i].x,&nodes[i].y,&nodes[i].z); Node s = nodes[0]; double t = 10; double ans = 0x3f3f3f3f; while(t>1e-8) { double d = 0; int k = 0; for(int i = 0; i < n; i++) { double dis = dist(s,nodes[i]); if(d