POJ 1379 (随机算法)模拟退火

 题目大意:

给定一堆点,找到一个点的位置使这个点到所有点中的最小距离最大

 

这里数据范围很小,精度要求也不高,我们这里可以利用模拟退火的方法,随机找到下一个点,如果下一个点比当前点优秀就更新当前点

 

参考:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

http://wenku.baidu.com/view/0c6b5df5f61fb7360b4c65a9.html

 

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 #include <algorithm>

 5 #include <climits>

 6 #include <cmath>

 7 #include <queue>

 8 #include <cstdlib>

 9 #include <ctime>

10 using namespace std;

11 #define random(x) ((rand()%x)+1)

12 #define N 1005

13 #define ll long long

14 #define eps 1e-4

15 const double PI = acos(-1.0);

16 const int INF = INT_MAX;

17 const int P = 20;

18 const int L = 30;

19 

20 double x,y;

21 int n;

22 double dist[N];

23 

24 struct Point{

25     double x,y;

26     Point(double x=0 , double y=0):x(x),y(y){}

27 }p[N] , tmp[N];

28 

29 double dis(Point a , Point b)

30 {

31     double x = a.x-b.x , y = a.y - b.y;

32     return sqrt(x*x+y*y);

33 }

34 

35 double min_dis(Point t)

36 {

37     double minn = 1e20;

38     for(int i=0 ; i<n ; i++) minn=min(minn , dis(t , p[i]));

39     return minn;

40 }

41 

42 bool ok(Point t)

43 {

44     return t.x>=0 && t.x<=x && t.y>=0 && t.y<=y;

45 }

46 

47 int main()

48 {

49     #ifndef ONLINE_JUDGE

50         freopen("a.in" , "r" , stdin);

51     #endif // ONLINE_JUDGE

52     srand(time(0));

53     int T;

54     scanf("%d" , &T);

55     while(T--)

56     {

57         Point ans;

58         double ret=0;

59 

60         scanf("%lf%lf%d" , &x , &y , &n);

61         for(int i=0 ; i<n ; i++){

62             scanf("%lf%lf" , &p[i].x , &p[i].y);

63         }

64 

65         for(int i=0 ; i<P ; i++){

66             tmp[i].x = random(1000)/1000.0*x;

67             tmp[i].y = random(1000)/1000.0*y;

68             dist[i] = min_dis(tmp[i]);

69         }

70         double step = sqrt(x*x+y*y)/2;

71         while(step>eps){

72 

73             for(int i=0 ; i<P ; i++){

74                 Point cur;

75                 for(int j=0 ; j<L ; j++){

76                     double ang = random(1000)/1000.0*2*PI;

77                     cur.x = tmp[i].x+cos(ang)*step;

78                     cur.y = tmp[i].y+sin(ang)*step;

79                     if(!ok(cur)) continue;

80                     double val = min_dis(cur);

81                     if(val>dist[i]){

82                         tmp[i]=cur;

83                         dist[i] = val;

84                     }

85                 }

86             }

87             step *= 0.85;

88         }

89 

90         for(int i=0 ; i<P ; i++){

91             if(dist[i]>ret){

92                 ret = dist[i];

93                 ans = tmp[i];

94             }

95         }

96         printf("The safest point is (%.1f, %.1f).\n" , ans.x , ans.y);

97     }

98     return 0;

99 }

 

你可能感兴趣的:(poj)