模拟退火,对着题解调了很久,但不知道哪里挂了。
#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
int x,y,w;
}arr[1005];
double energy(double x,double y)
{
double p=0;
for(int i=1;i<=n;++i)
{
double dx=x-arr[i].x;
double dy=y-arr[i].y;
p+=sqrt(dx*dx+dy*dy)*arr[i].w;
}
return p;
}
double ansx,ansy,ans;
#define end 1e-9
#define delta 0.996
#define times 10
void init()
{
srand(time(0));
for(int i=1;i<=n;++i)
ansx+=arr[i].x,ansy+=arr[i].y;
ansx/=n,ansy/=n;
ans=energy(ansx,ansy);
}
void sa()
{
double tem=3000;
while(tem>end)
{
double nowx=ansx+(rand()*2-RAND_MAX)*tem;
double nowy=ansy+(rand()*2-RAND_MAX)*tem;
double now=energy(nowx,nowy);
double dnow=now-ans;
if(dnow<0)
{
ans=now;
ansx=nowx;
ansy=nowy;
}
else if(exp(-delta/tem)*RAND_MAX>rand())
{
ansx=nowx;
ansy=nowy;
}
tem*=delta;
}
}
void solve()
{
init();
sa();
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d %d %d",&arr[i].x,&arr[i].y,&arr[i].w);
}
solve();
printf("%.3lf %.3lf\n",ansx,ansy);
return 0;
}