06年论文里的题
正解是voronoi图
然而我看了半天也不会QAQ
构造算法太复杂了
然后写了个模拟退火水一水。。。。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
using namespace std;
double sqr(double x){return x*x;}
const double pi=acos(-1.0);
const double eps=1e-9;
struct point{
double x,y;
}p[1005],xx[30];
double bx[30];
int n;
double dist(point a,point b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
double calc(point a){
double ans=dist(p[1],a);
for(int i=2;i<=n;i++)
ans=min(ans,dist(p[i],a));
return ans;
}
double x,y;
bool in(point p){
return p.x>-eps&&p.x<x+eps&&p.y>-eps&&p.y<y+eps;
}
int main(){
//freopen("a.in","r",stdin);
//srand(time(0));
int Cas;
scanf("%d",&Cas);
while(Cas--){
scanf("%lf%lf%d",&x,&y,&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=1;i<=17;i++){
xx[i].x=(rand()%1000+1)/1000.0*x;
xx[i].y=(rand()%1000+1)/1000.0*y;
bx[i]=calc(xx[i]);
}
double T=max(x,y)/sqrt(1.0*n);
while(T>1e-3){
for(int i=1;i<=17;i++){
point now,last=xx[i];
for(int j=1;j<=31;j++){
double angle=(rand()%1000+1)/1000.0*2*pi;
now.x=last.x+cos(angle)*T;
now.y=last.y+sin(angle)*T;
if(!in(now))continue;
double tmp=calc(now);
if(tmp>bx[i]){
bx[i]=tmp;
xx[i]=now;
}
}
}
T*=0.83;
}
int id=0;
double ans=0;
for(int i=1;i<=17;i++)
if(bx[i]>ans){
ans=bx[i];
id=i;
}
printf("The safest point is (%.1f, %.1f).\n",xx[id].x,xx[id].y);
}
return 0;
}