思路:
首先平衡点貌似是平面上这些点的广义费马点.广义费马点就是到所有点的距离与权值的乘积之和最小的一个点.
(这为什么我并不知道)
不过有了这个就可以用模拟退火随便玩了.
(你们感受一下代码长度)
#include<cstdio> #include<cstring> #include<cctype> #include<iostream> #include<algorithm> #include<cmath> using namespace std; typedef double f2; #define N 10010 int n;f2 x[N],y[N],w[N]; f2 sqr(f2 dx){return dx*dx;} f2 calc(f2 dx,f2 dy){ f2 res=0; for(int i=1;i<=n;++i)res+=sqrt(sqr(dx-x[i])+sqr(dy-y[i]))*w[i]; return res; } f2 get(){ int d=rand()%1000; return (rand()&1?-1:1)*(d/1000.0); } int main(){ scanf("%d",&n);register int i,j; f2 addx=0,addy=0;for(i=1;i<=n;++i)scanf("%lf%lf%lf",&x[i],&y[i],&w[i]),addx+=x[i],addy+=y[i]; addx/=n,addy/=n; f2 ansx,ansy,ans; f2 nowx=addx,nowy=addy,nowans=calc(nowx,nowy),nxtx,nxty,nxtans; ans=nowans,ansx=nowx,ansy=nowy; f2 T=1e6; for(;T>1e-3;T*=0.993){ nxtans=calc(nxtx=nowx+T*get(),nxty=nowy+T*get()); if(nxtans<ans)ans=nxtans,ansx=nxtx,ansy=nxty; if(nxtans<nowans||exp((nowans-nxtans)/T)>fabs(get()))nowans=nxtans,nowx=nxtx,nowy=nxty; } for(i=1;i<=1000;++i){ nxtans=calc(nxtx=ansx+T*get(),nxty=ansy+T*get()); if(nxtans<ans)ans=nxtans,ansx=nxtx,ansy=nxty; } printf("%.3lf %.3lf",ansx,ansy); return 0; }