poj2728 Desert King(最优比率生成树【Prim)
2018-03-04 15:49
351 查看
题目链接
分析:
最小化:∑cost∑len∑cost∑len
01分数规划:最优比率生成树
渠道的长度是两个村庄之间的水平距离,通道的成本是升降机的高度
题目约定:
He just needs to build the necessary channels to bring water to all the villages, which means there will be only one way to connect each village to the capital
那么我们就需要找到一棵生成树
设函数F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]=∑(cost[i]−L∗len[i])∗x[i]F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]=∑(cost[i]−L∗len[i])∗x[i]
因为L越大d值越小
我们的目标是使∑cost∑len∑cost∑len尽量小
即L>∑cost∑len,F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]<0L>∑cost∑len,F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]<0
当F(L)<0F(L)<0时,L的范围可以进一步缩小
二分答案,把每条边的边权设为d[i]=cost[i]−L∗len[i]d[i]=cost[i]−L∗len[i],之后用最小生成树判断
因为是稠密图(完全图),推荐使用Prim算法计算生成树
没写过Prim?一学就会!
分析:
最小化:∑cost∑len∑cost∑len
01分数规划:最优比率生成树
渠道的长度是两个村庄之间的水平距离,通道的成本是升降机的高度
题目约定:
He just needs to build the necessary channels to bring water to all the villages, which means there will be only one way to connect each village to the capital
那么我们就需要找到一棵生成树
设函数F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]=∑(cost[i]−L∗len[i])∗x[i]F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]=∑(cost[i]−L∗len[i])∗x[i]
因为L越大d值越小
我们的目标是使∑cost∑len∑cost∑len尽量小
即L>∑cost∑len,F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]<0L>∑cost∑len,F(L)=∑cost[i]∗x[i]−L∗∑len[i]∗x[i]<0
当F(L)<0F(L)<0时,L的范围可以进一步缩小
二分答案,把每条边的边权设为d[i]=cost[i]−L∗len[i]d[i]=cost[i]−L∗len[i],之后用最小生成树判断
因为是稠密图(完全图),推荐使用Prim算法计算生成树
没写过Prim?一学就会!
#include<cstdio> #include<cstring> #include<iostream> #include<cmath> using namespace std; const int N=1002; const double eps=1e-6; const double INF=1e10; double cost ,dis ,d ; int n,m; struct node{ double x,y,z; }; node a ; double Dis(int i,int j) { return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); } bool vis ; double v ; int check(double x) { for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) d[i][j]=d[j][i]=cost[i][j]-x*dis[i][j]; double sum=0; int cur=1; vis[1]=1; v[1]=0.0; //到结点i的最短边 for (int i=2;i<=n;i++) vis[i]=0,v[i]=INF; for (int o=1;o<n;o++) { double mn=INF; int k; for (int i=1;i<=n;i++) if (!vis[i]) { if (d[cur][i]<v[i]) v[i]=d[cur][i]; if (v[i]<mn) mn=v[i],k=i; } vis[k]=1; sum+=mn; cur=k; } return sum<=0; } int main() { while (scanf("%d",&n)!=EOF&&n) { double l=0,r=0,ans=INF; for (int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z); for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) { cost[i][j]=cost[j][i]=fabs(a[i].z-a[j].z); dis[i][j]=dis[j][i]=Dis(i,j); r=max(r,cost[i][j]/dis[i][j]); } while (r-l>=eps) { double mid=(l+r)/2; if (check(mid)) ans=min(ans,mid),r=mid; else l=mid; } printf("%0.3lf\n",ans); } return 0; }
相关文章推荐
- poj_2728 Desert King(最优比率生成树+01分数规划+二分+prim)
- POJ 2728 Desert King(最优比率生成树) prim+二分
- 【POJ】【2728】 Desert King 最优比率生成树
- POJ 2728 Desert King 最优比率生成树
- POJ 2728 Desert King ★(01分数规划介绍 && 应用の最优比率生成树)
- POJ 题目2728 Desert King(最优比率生成树)
- poj 2728 Desert King(最优比率生成树)
- POJ 2728 Desert King ★(01分数规划介绍 && 应用の最优比率生成树)
- POJ 2728 Desert King(最优比率生成树 01分数规划)
- POJ 2728 Desert King(最优比率生成树)
- POJ 2728-Desert King(01分数规划_最优比率生成树)
- POJ 2728 Desert King(最优比率生成树)
- POJ 2728 Desert King 01分数规划,最优比率生成树
- POJ 2728 Desert King 最优比率生成树
- POJ-2728 Desert King 01参数规划-最优比率生成树
- 【POJ】2728 Desert King 最优比率生成树——01分数规划【经典】
- poj 2728 Desert King(最优比率生成树)
- POJ 2728 Desert King [最优比率生成树]
- POJ 2728 Desert King (最优比率生成树---01分数规划)
- Desert King (poj 2728 最优比率生成树 0-1分数规划)