1. 程式人生 > >POJ 1379 模擬退火

POJ 1379 模擬退火

一個 不能 pri 最短 clas pac nsx 思路 using

模擬退火算法,很久之前就寫過一篇文章了。雙倍經驗題(POJ 2420)

題意:

在一個矩形區域內,求一個點的距離到所有點的距離最短的那個,最大。

這個題意,很像二分定義,但是毫無思路,也不能暴力枚舉,那就模擬退火。

#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;

const int maxn = 1005;

int X,Y,M;
int Kase;

struct Node {
    double x,y;
}nodes[maxn];

int dx[4] = {0,0,-1,1}; int dy[4] = {-1,1,0,0}; double dist(Node a,Node b) { return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } double calc(Node p) { double ret = 0x3f3f3f3f; for(int i = 0; i < M; i++) ret = min(ret,dist(p,nodes[i])); return ret; } int main() {
//freopen("in.txt","r",stdin); scanf("%d",&Kase); while(Kase--) { scanf("%d%d%d",&X,&Y,&M); for(int i = 0; i < M; i++) scanf("%lf%lf",&nodes[i].x,&nodes[i].y); Node s; s.x = X/2; s.y = Y/2; double t = max(X,Y);
double ansx = X/2; double ansy = Y/2; double ans = calc(s); Node tmp; tmp.x = 0; tmp.y = 0; double anstmp = calc(tmp); if(anstmp>ans) { ans = anstmp; ansx = 0; ansy = 0; } tmp.x = 0; tmp.y = Y; anstmp = calc(tmp); if(anstmp>ans) { ans = anstmp; ansx = 0; ansy = Y; } tmp.x = X; tmp.y = 0; anstmp = calc(tmp); if(anstmp>ans) { ans = anstmp; ansx = X; ansy = 0; } tmp.x = X; tmp.y = Y; anstmp = calc(tmp); if(anstmp>ans) { ans = anstmp; ansx = X; ansy = Y; } while(t>1e-8) { bool flag = true; while(flag) { flag = false; for(int i = 0; i < 4; i++) { Node v; v.x = s.x + dx[i]*t; v.y = s.y + dy[i]*t; if(v.x>X||v.y>Y||v.x<0||v.y<0) continue; double tp = calc(v); if(tp>ans) { ans = tp; flag = true; ansx = v.x; ansy = v.y; s = v; } } } t = t*0.98; } printf("The safest point is (%.1f, %.1f).\n",ansx,ansy); } return 0; }

POJ 1379 模擬退火