# 模拟退火

 1 #include <iostream>
2 #include <algorithm>
3 #include <cstdlib>
4 #include <cmath>
5 #include <ctime>
6 #include <cstdio>
7 using namespace std;
8 struct Point
9 {
10     double x,y;
11 }a[105];
12 int n;
13 double dis(double x,double y,Point a)
14 {
15     return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
16 }
17 double Getans(double x,double y)
18 {
19     double ans=0.0;
20     for (int i=1;i<=n;i++)
21         ans+=dis(x,y,a[i]);
22     return ans;
23 }
24 int main()
25 {
26     //srand((unsigned)time(0));
27     while (scanf("%d",&n)!=EOF)
28     {
29         double x=0,y=0,t=1e5,ans=1e20;
30         for (int i=1;i<=n;i++)
31         {
32             scanf("%lf%lf",&a[i].x,&a[i].y);
33             x+=a[i].x,y+=a[i].y;
34         }
35         x/=n,y/=n;
36         ans=Getans(x,y);
37         while (t>0.02)
38         {
39             double tx,ty;
40             tx=0,ty=0;
41             for (int i=1;i<=n;i++)
42             {
43                 tx+=(a[i].x-x)/dis(x,y,a[i]);
44                 ty+=(a[i].y-y)/dis(x,y,a[i]);
45             }
46             double tmp=Getans(x+tx*t,y+ty*t);
47             if (tmp<ans)
48                 ans=tmp,x+=tx*t,y+=ty*t;
49             else if (t>(double)(rand()%100000))
50                 ans=tmp,x+=tx*t,y+=ty*t;
51             t*=0.9;
52         }
53         printf("%.0f\n",ans);
54     }
55     return 0;
56 } 

posted @ 2017-10-15 19:53  weeping  阅读(159)  评论(0编辑  收藏  举报