【退火!!!退火!!!】poj2420
来源:互联网 发布:js 数组 slice 编辑:程序博客网 时间:2024/04/29 12:48
http://poj.org/problem?id=2420
题目大意就是说给你n个点让你求一个到所有点的和最短的点(n<100)
然后很明显是个搜索的题,感觉爬山什么的也可以做
但是退火大法做不是更233吗,于是就退火退火……
退火就不再多说,这里想说一个类似于离散化点的做法参考了黄学长orz
程序如下:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<queue>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<ctime>#include<stack>#define INF 2100000000#define ll long long#define clr(x) memset(x,0,sizeof(x))#define maxclr(x) memset(x,127,sizeof(x))using namespace std;#define M 105struct point{ double x,y; point(double x=0,double y=0):x(x),y(y){}}a[M],t[M];const int tim=100;double maxx,maxy,minx,miny,ans=1E100,T,best[tim+1];double sumx,sumy,sx,sy;const double eps=1E-8;const double TUI=0.9;const double T_min=1e-4;inline point read(){ point ret=0; char c; while(!(c>='0'&&c<='9')) c=getchar(); while(c>='0'&&c<='9') { ret.x=(c-'0')+ret.x*10; c=getchar(); } maxx=max(maxx,ret.x); minx=min(minx,ret.x); while(!(c>='0'&&c<='9')) c=getchar(); while(c>='0'&&c<='9') { ret.y=(c-'0')+ret.y*10; c=getchar(); } maxy=max(maxy,ret.y); miny=min(miny,ret.y); sumx+=ret.x; sumy+=ret.y; return ret;}double dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int n;double rand01(){ double t1=(double)(rand()%1000)/(double)1000, t2=(double)(rand()%1000)/(double)1000; double r=t1+t2*0.001; return r;}double randd(double l,double r){ return l+(r-l)*rand01();}point rand_point(point a,double b){ double l=a.x-b,r=a.x+b; double x=randd(l,r); l=a.y-b;r=a.y+b; double y=randd(l,r); return point(x,y);}double get_ans(point x){ double ret=0; for(int i=1;i<=n;i++) ret+=dis(x,a[i]); return ret;}void tuihuo(){ T=max(maxx-minx,maxy-miny); t[1]=point(maxx,maxy); t[2]=point(maxx,miny); t[3]=point(minx,maxy); t[4]=point(minx,miny); t[5]=point((maxx+minx)/2,(maxy+miny)/2); t[6]=point(sumx/(double)n,sumy/(double)n); maxclr(best); best[0]=0; for(int i=7;i<=tim;i++) t[i]=rand_point(t[5],T); for(int i=1;i<=tim;i++) best[i]=get_ans(t[i]); while(T>T_min) { for(int i=1;i<=tim;i++) { sx=0,sy=0; for(int j=1;j<=n;j++)//这个就是黄学长orz的离散做法 { double d=dis(t[i],a[j]); if(d>-eps&&d<eps)continue; sx+=(a[j].x-t[i].x)/d; sy+=(a[j].y-t[i].y)/d; } //sx/=n;这两排加不加都可以,我感觉应该加上去的 //sy/=n; point now=point(t[i].x+T*sx,t[i].y+T*sy); double temp=get_ans(now); if(temp<best[i]||exp(best[i]-temp)/T>rand01()) { t[i]=now; best[i]=temp; } } T*=TUI; } for(int i=1;i<=tim;i++) ans=min(ans,best[i]);}int main(){ freopen("in.txt","r",stdin); srand((unsigned)time(0)); cin>>n; for(int i=1;i<=n;i++) a[i]=read(); tuihuo(); printf("%.0f",ans);}
大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。
0 0
- 【退火!!!退火!!!】poj2420
- POJ2420模拟退火
- poj2420(模拟退火)
- poj2420 模拟退火
- POJ2420 & HDU1109 模拟退火
- [POJ2420]模拟退火
- POJ2420 费马点问题求解 随机化 模拟退火
- 模拟退火算法A Star not a Tree?(poj2420)
- 【模拟退火,广义费马点】POJ2420 A Star not a Tree?
- poj2420 A Star not a Tree?【模拟退火】
- [Poj2420]A Star not a Tree? (爬山算法||模拟退火算法)
- A Star not a Tree?——poj2420 费马点退火算法(伪)
- 模拟退火
- 退火算法
- 模拟退火
- 模拟退火
- 模拟退火
- 模拟退火
- OpenCv中,文件存储类FileStorage类源代码详解
- Ubuntu 16.04 无法上网
- HDU 3709 数位DP
- 分布式系统互斥性与幂等性问题的分析与解决
- Vocaloid简介
- 【退火!!!退火!!!】poj2420
- Oracle的TX锁(行级锁、事务锁)
- 学习linux之 cmake(1)
- ValueAnimator是如何动起来的
- Html5旋转立方体3D动态实例
- poj3020——Antenna Placement(最小边覆盖)
- Mob社会化分享和Fragment手势切换
- 用MaterialRefreshLayout实现下拉刷新 上拉加载更多
- 51Nod-1732-51Nod婚姻介绍所