poj 2728 最优比率生成树
来源:互联网 发布:lt1953wa淘宝 编辑:程序博客网 时间:2024/06/06 05:11
思想的话看这里
http://www.cnblogs.com/lotus3x/archive/2009/03/21/1418480.html
二分法:
/*the length of the channel is the horizontal distance between the two villages. The cost of the channel is the height of the lifter. 最优比率生成树poj 2728目标:min{∑costi/∑leni}逼近的思想,∑costi/∑leni<=x,即 ∑(costi-x*leni)<=0 是一个单调递减函数 即求边为costi-x*leni的 MST */#include<stdio.h>#include<string.h>#include<math.h>const double inf = 1e20;const int N = 1010;const double eps = 1e-8;struct point {double x,y,z;}p[N];int n,m;int flag[N];double D[N];double len[N][N];double cost[N][N];double map[N][N];double prime(){ int i,v,k; double ret=0,mi; for(i=1;i<=n;i++){ flag[i]=0; D[i]=inf; }D[1]=0;flag[1]=1;v=1; for(k=1;k<n;k++){ for(i=1;i<=n;i++)if(!flag[i]){ if(map[v][i]<D[i]) D[i]=map[v][i]; } mi=inf; for(i=1;i<=n;i++) if(!flag[i]&&D[i]<mi) mi=D[v=i]; flag[v]=1; ret+=mi; }//printf("ret=%.2lf\n",ret);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));}double solve(double mid){ int i,j; for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)map[i][j]=map[j][i]=cost[i][j]-mid*len[i][j]; return prime();}int main(){int i,j,k;while(scanf("%d",&n),n){ for(i=1;i<=n;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { len[i][j]=len[j][i]=dis(p[i],p[j]); cost[i][j]=cost[j][i]=fabs(p[i].z-p[j].z); } double a=0,b; for(i=1;i<=n;i++) map[i][i]=0.0; double l=0.0,r=100.0,mid; while(fabs(l-r)>eps) { mid=(l+r)/2; if(solve(mid)>eps) l=mid; else r=mid; } printf("%.3lf\n",r); }return 0;}
迭代法:不用去管上下界,随意代入即可,此时求的是∑costi/∑leni的值,代码修改一下就好,迭代法的效率灰常高啊,上面的是迭代
#include<stdio.h>#include<string.h>#include<math.h>const double inf = 1e20;const int N = 1010;const double eps = 1e-8;struct point {double x,y,z;}p[N];int n,m;int flag[N];double D[N],len[N][N],cost[N][N],map[N][N];int pre[N];double dis(point a,point b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double prime(){ int i,v,k; double cost=0,len=0,mi;memset(flag,0,sizeof(flag)); for(i=1;i<=n;i++) D[i]=inf; D[1]=0;flag[1]=1;v=1; for(k=1;k<n;k++){ for(i=1;i<=n;i++)if(!flag[i]&&map[v][i]<D[i]){D[i]=map[v][i];pre[i]=v;}mi=inf;for(i=1;i<=n;i++)if(!flag[i]&&D[i]<mi)mi=D[v=i];flag[v]=1;cost+=fabs(p[pre[v]].z-p[v].z);len+=dis(p[pre[v]],p[v]);}return cost/len;}double solve(double mid){int i,j;for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)map[i][j]=map[j][i]=cost[i][j]-mid*len[i][j]; return prime();}int main(){int i,j;while(scanf("%d",&n),n){for(i=1;i<=n;i++)scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);for(i=1;i<=n;i++)for(j=i+1;j<=n;j++){len[i][j]=len[j][i]=dis(p[i],p[j]);cost[i][j]=cost[j][i]=fabs(p[i].z-p[j].z);}for(i=1;i<=n;i++)map[i][i]=0.0;double a=0,b;while(1){b=solve(a);if(fabs(a-b)<eps) break;a=b;}printf("%.3lf\n",b);}return 0;}
- poj 2728 最优比率生成树
- POJ 2728 最优比率生成树
- POJ 2728 最优比率生成树
- POJ 2728 最优比率生成树
- (最优比率生成树 )POJ 2728
- POJ 2728 最优比率生成树
- POJ 2728 最小生成树 求最优比率生成树
- POJ 2728 最优比率生成树 01分数规划问题
- poj 2728 Desert King(最优比率生成树)
- poj 2728 Desert King(最优比率生成树)
- POJ 2728 Desert King(最优比率生成树) prim+二分
- 【POJ】【2728】 Desert King 最优比率生成树
- POJ 2728 Desert King (最优比率生成树)
- poj 2728 最优比率生成树(国王修运河)
- poj 2728 Desert King 最优比率生成树 分数规划
- poj 2728 Desert King (最优比率生成树)
- POJ 2728 Desert King(初遇最优比率生成树)
- poj 2728 Desert King(最优比率生成树)
- hdu 1063 java 高精度
- 斐波那契数 java
- hdu 1753 java 小数相加
- poj 3140 简单dfs
- poj 3207 2-sat
- poj 2728 最优比率生成树
- hdu 3062 2-sat 水题
- poj 3678 2-sat 建图非常容易错!!
- hdu 1423 最长公共上升子序列
- poj 3624 01背包
- poj 3628 01背包
- poj 3211 01 背包
- poj 1745 dp
- 多校第一场