题目 http://poj.org/problem?id=2728

关键词:0/1分数规划,参数搜索,二分法,dinkelbach

参考资料:http://hi.baidu.com/zzningxp/item/28aa46e0fd86bdc2bbf37d03

http://hi.baidu.com/zheng6822/item/b31fbe9d5ae17536336eeb8f

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<stdlib.h>
  6. #include<math.h>
  7. #define N 1010
  8. #define INF 1e15
  9. #define eps 1e-10
  10. using namespace std;
  11. double X[N],Y[N],Z[N];
  12. double cost[N][N];
  13. double lowcost[N];
  14. int closest[N];int vis[N];
  15. int n;double r;
  16. double disc(int i,int j)
  17. {
  18. return fabs(Z[i]-Z[j]);
  19. }
  20. double disd(int i,int j)
  21. {
  22. return sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
  23. }
  24. double prim(double r)
  25. {
  26. double sumc=;double sumd=;
  27. for(int i=;i<n;i++)
  28. for(int j=;j<n;j++)
  29. {
  30. if(i==j)
  31. cost[i][j]=INF;
  32. else
  33. cost[i][j]=disc(i,j)-r*disd(i,j);
  34. }
  35. for(int i=;i<n;i++)
  36. {
  37. lowcost[i]=cost[][i];
  38. vis[i]=;
  39. closest[i]=;
  40. }
  41. closest[]=;
  42. vis[]=;
  43. int k;
  44. for(int i=;i<n;i++)
  45. {
  46. double tmp=INF;
  47. for(int j=;j<n;j++)
  48. if(!vis[j]&&tmp>lowcost[j])
  49. {
  50. k=j;
  51. tmp=lowcost[j];
  52. }
  53. vis[k]=;
  54. for(int j=;j<n;j++)
  55. if(!vis[j]&&lowcost[j]>cost[k][j])
  56. {
  57. lowcost[j]=cost[k][j];
  58. closest[j]=k;
  59. }
  60. }
  61. for(int i=;i<n;i++)
  62. {
  63. sumc+=disc(i,closest[i]);
  64. sumd+=disd(i,closest[i]);
  65. }
  66. return sumc/sumd;
  67. }
  68. int main()
  69. {
  70. while(scanf("%d",&n)!=EOF&&n)
  71. {
  72. for(int i=;i<n;i++)
  73. cin>>X[i]>>Y[i]>>Z[i];
  74. double r1=,r2=;
  75. while()
  76. {
  77. r2=prim(r1);
  78. if(fabs(r1-r2)<=eps)
  79. break;
  80. r1=r2;
  81. }
  82. printf("%.3f\n",r1);
  83. }
  84. return ;
  85. }

PRIM+迭代法

主要算法部分的分析

  1. double prim(double r)
  2. {
  3. /*根据题目要求和算法得到由新的权值组成的图,并且写出邻接矩阵*/
  4. double sumc=0;double sumd=0;
  5. for(int i=0;i<n;i++)
  6. for(int j=0;j<n;j++)
  7. {
  8. if(i==j)
  9. cost[i][j]=INF;
  10. else
  11. cost[i][j]=disc(i,j)-r*disd(i,j);
  12. }
  13. /*初始化*/
  14. for(int i=0;i<n;i++)
  15. {
  16. lowcost[i]=cost[0][i];
  17. vis[i]=0; /*判断该点是否已经在集合内*/
  18. closest[i]=0; /*邻接点*/
  19. }
  20. /*将第一个点加入集合*/
  21. closest[0]=0;
  22. vis[0]=1;
  23. int k;
  24. for(int i=0;i<n;i++)
  25. {
  26. double tmp=INF;
  27. /*通过一次循环找到与第一个点距离最短的点*/
  28. for(int j=0;j<n;j++)
  29. if(!vis[j]&&lowcosat[j]<tmp)
  30. {
  31. k=j;
  32. tmp=lowcost[j];
  33. }
  34. /*将该点加入集合中*/
  35. vis[k]=1;
  36. /*这一步是更新其他的点到集合中的点的距离,closest是用来记录该点的前驱的点的数组,lowcost是用来记录其他点到MST的最短距离的数组,注意是到树上任意一点而不是其中某点*/
  37. for(int j=0;j<n;j++)
  38. if(!vis[j]&&lowcost[j]>cost[j][k])
  39. {
  40. lowcost[j]=cost[j][k];
  41. closest[j]=k;
  42. }
  43. }
  44. /*返回参数,用于迭代*/
  45. for(int i=0;i<n;i++)
  46. {
  47. sumc+=disc(i,closest[i]);
  48. sumd+=disd(i,closest[i]);
  49. }
  50. return sumc/sumd;
  51. }

  

POJ2728 Desert King 最优比率生成树的更多相关文章

  1. POJ2728 Desert King —— 最优比率生成树 二分法

    题目链接:http://poj.org/problem?id=2728 Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Subm ...

  2. POJ 2728 Desert King 最优比率生成树

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20978   Accepted: 5898 [Des ...

  3. 【POJ2728】Desert King 最优比率生成树

    题目大意:给定一个 N 个点的无向完全图,边有两个不同性质的边权,求该无向图的一棵最优比例生成树,使得性质为 A 的边权和比性质为 B 的边权和最小. 题解:要求的答案可以看成是 0-1 分数规划问题 ...

  4. Desert King(最优比率生成树)

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 22717   Accepted: 6374 Desc ...

  5. POJ.2728.Desert King(最优比率生成树 Prim 01分数规划 二分/Dinkelbach迭代)

    题目链接 \(Description\) 将n个村庄连成一棵树,村之间的距离为两村的欧几里得距离,村之间的花费为海拔z的差,求花费和与长度和的最小比值 \(Solution\) 二分,假设mid为可行 ...

  6. POJ 2728 Desert King(最优比率生成树, 01分数规划)

    题意: 给定n个村子的坐标(x,y)和高度z, 求出修n-1条路连通所有村子, 并且让 修路花费/修路长度 最少的值 两个村子修一条路, 修路花费 = abs(高度差), 修路长度 = 欧氏距离 分析 ...

  7. POJ 2728 Desert King (最优比率树)

    题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目 ...

  8. poj-2728Desert King(最优比率生成树)

    David the Great has just become the king of a desert country. To win the respect of his people, he d ...

  9. POJ 2728 Desert King (最优比例生成树)

    POJ2728 无向图中对每条边i 有两个权值wi 和vi 求一个生成树使得 (w1+w2+...wn-1)/(v1+v2+...+vn-1)最小. 采用二分答案mid的思想. 将边的权值改为 wi- ...

随机推荐

  1. 2.2 The Object Model -- Reopening Classes and Instances

    1. 你不需要一开始定义一个类的全部内容,你可以通过使用reopen方法重新打开一个类并定义新的属性. Person.reopen({ isPerson: true }); Person.create ...

  2. forEach方法的实现

    var arr = [1, 23, 1, 1, 1, 3, 23, 5, 6, 7, 9, 9, 8, 5]; Array.prototype.forEach = Array.prototype.fo ...

  3. cocos进阶教程(3)Lua加密技术

    如果开发者不想让游戏中的资源或脚本文件轻易的暴露给其他人,一般会采用对文件进行加密的方式来保护文件或资源被盗用.Quick-Cocos2d-x 为开发者提供了xxtea加密算法,用来对脚本文件及资源进 ...

  4. 对Java平台的理解

    1)  Java是一种面向对象的语言(封装,继承,多态),最显著的特性有两个方面: ----书写一次,到处运行(Write once,run anywhere) 能够非常容易的获得跨平台的能力 --- ...

  5. 离线安装Cloudera Manager5.2.0和CDH5 2.0

    第一次安装出现了各种问题,尤其是对于不是太熟悉linux系统的更是头疼不已呀!特此记录一下,希望能够让小伙伴们少走点弯路. 1.给机器添加路由 (根据自己的机器情况,可以忽略)   route add ...

  6. 使用idea创建JavaWeb项目

    [第一步] File---New---Project [第二步] 选择Java Enterprise版本,然后配置tomcat 注意:这里关联的tomcat home指的是tomcat的解压目录(bi ...

  7. Tcp/Ip:Telnet指令

    作用: 1,客户端连接服务端,并对服务端操作: (此功能已逐渐废弃,代替他的远程桌面): 2,telnet ip地址 端口号   用来测试Ip地址下,端口号是否可以被访问

  8. HDU 2896 病毒侵袭(AC自动机)题解

    题意:给你n个模式串,再给你m个主串,问你每个主串中有多少模式串,并输出是哪些.注意一下,这里给的字符范围是可见字符0~127,所以要开130左右. 思路:用字典树开的时候储存编号,匹配完成后set记 ...

  9. 【Java----字符串转义与反转义】

    apache工具包common-lang中有一个很有用的处理字符串的工具类,其中之一就是StringEscapeUtils,这个工具类是在2.3版本以上加上的去的,利用它能很方便的进行html,xml ...

  10. 【安装】Nginx安装

    系统平台:CentOS release 6.5 (Final) 64位. 安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool ...