题解:使用模拟退火算法,关于模拟退火算法的讲解传送门
题解:只要使得也就是总的重力势能最小,就可以使系统平衡,所以通过模拟退火算法进行随机模拟
附上代码:
#include<bits/stdc++.h>
using namespace std;
const double delta=0.993;
struct Node{
int x,y,weight;
};
Node node[10005];
int n;
double xans,yans;
double ans=1e18+7,t;
double potential_energy(double nowx,double nowy)
{
double sum=0;
for(int i=1;i<=n;i++){
double delx=nowx-node[i].x;
double dely=nowy-node[i].y;
sum+=(sqrt(delx*delx+dely*dely)*node[i].weight);
}
return sum;
}
void simulta_anneal()
{
t=1926;
while(t>1e-14){
double xtemp=xans+(rand()*2-RAND_MAX)*t;
double ytemp=yans+(rand()*2-RAND_MAX)*t;
double new_ans=potential_energy(xtemp,ytemp);
double de=new_ans-ans;
if(de<0){
xans=xtemp;
yans=ytemp;
ans=new_ans;
}else if(exp(-de/t)*RAND_MAX>rand()){
xans=xtemp;
yans=ytemp;
}
t*=delta;
}
}
void sa()
{
simulta_anneal();
simulta_anneal();
simulta_anneal();
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].weight);
}
sa();
printf("%.3f %.3f",xans,yans);
return 0;
}