题意:给n个点,可以将每个点的x,y的欧几里得距离(就是坐标系里两点距离公式)看作距离,z的差值即为费用差,求的是所有最小生成树中的min(边费用和/边距离和)。

思路:其实挑战P143有类似的列题,用的是二分枚举答案的方法,只不过不是树。这一题仅仅需要将题给图找出最小生成树,然后同样枚举即可。

虽然网上有许多高级的名词什么最优比率xxx之类的。。以及迭代的方法,不过我认为用二分也很好,易于想到也可以加深理解。

 #include <iostream>

 #include <string>

 #include <cstdio>

 #include <cstring>

 #include <cstdlib>

 #include <algorithm>

 #include <cmath>

 #define MAXN 1005

 #define INF 1000000000

 #define eps 1e-7

 using namespace std;

 int n;

 double Edge[MAXN][MAXN], lowcost[MAXN];

 int nearvex[MAXN];

 struct Point

 {

     int x, y, z;

 }p[MAXN];

 double cal(int a, int b)

 {

     return sqrt(1.0 * (p[a].x - p[b].x) * (p[a].x - p[b].x) + 1.0 * (p[a].y - p[b].y) * (p[a].y - p[b].y));

 }

 double prim(int src, double l)

 {

     double cost = , len = ;

     double sum = ;

     for(int i = ; i <= n; i++)

     {

         nearvex[i] = src;

         lowcost[i] = abs(p[src].z - p[i].z) - Edge[src][i] * l;

     }

     nearvex[src] = -;

     for(int i = ; i < n; i++)

     {

         double mi = INF;

         int v = -;

         for(int j = ; j <= n; j++)

             if(nearvex[j] != - && lowcost[j] < mi)

             {

                 v = j;

                 mi = lowcost[j];

             }

         if(v != -)

         {

             cost += abs(p[nearvex[v]].z - p[v].z);

             len += Edge[nearvex[v]][v];

             nearvex[v] = -;

             sum += lowcost[v];

             for(int j = ; j <= n; j++)

             {

                 double tmp = abs(p[v].z - p[j].z) - Edge[v][j] * l;

                 if(nearvex[j] != - && tmp < lowcost[j])

                 {

                     lowcost[j] = tmp;

                     nearvex[j] = v;

                 }

             }

         }

     }

     return sum;

 }

 int main()

 {

     while(scanf("%d", &n) != EOF && n)

     {

         for(int i = ; i <= n; i++)

             scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);

         for(int i = ; i <= n; i++)

             for(int j = ; j <= n; j++)

                 Edge[i][j] = cal(i, j);

         double low = , high = 10.0;             //其实二分20多次已经很足够了

         double l = 0.0, r = 100.0, mid;

         while(r - l > eps)

         {

             mid = (l + r) / ;

             if(prim(, mid) >= ) l = mid;

             else r = mid;

         }

         printf("%.3f\n", r);

     }

     return ;

 }

POJ 2728 二分+最小生成树的更多相关文章

  1. POJ 2728 Desert King(最优比例生成树 二分 | Dinkelbach迭代法)

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 25310   Accepted: 7022 Desc ...

  2. POJ - 2018 二分+单调子段和

    依然是学习分析方法的一道题 求一个长度为n的序列中的一个平均值最大且长度不小于L的子段,输出最大平均值 最值问题可二分,从而转变为判定性问题:是否存在长度大于等于L且平均值大于等于mid的字段和 每个 ...

  3. [国家集训队2012]tree(陈立杰) 题解(二分+最小生成树)

    tree 时间限制: 3 Sec  内存限制: 512 MB 题目描述 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入 第一行V, ...

  4. POJ 2728 JZYZOJ 1636 分数规划 最小生成树 二分 prim

    http://172.20.6.3/Problem_Show.asp?id=1636 复习了prim,分数规划大概就是把一个求最小值或最大值的分式移项变成一个可二分求解的式子. #include< ...

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

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

  6. Desert King POJ - 2728(最优比率生产树/(二分+生成树))

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

  7. 最优比率生成树 POJ 2728 迭代或者二分

    别人解题报告的链接: http://blog.sina.com.cn/s/blog_691190870101626q.html 说明一下关于精度的问题,当结果是精确到小数点后3为,你自然要把误差定为至 ...

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

    Desert King http://poj.org/problem?id=2728 Time Limit: 3000MS   Memory Limit: 65536K       Descripti ...

  9. POJ 2728 Desert King | 01分数规划

    题目: http://poj.org/problem?id=2728 题解: 二分比率,然后每条边边权变成w-mid*dis,用prim跑最小生成树就行 #include<cstdio> ...

随机推荐

  1. 跨站脚本(XSS)攻击

    https://blog.csdn.net/extremebingo/article/details/81176394

  2. 吴裕雄--天生自然深度学习TensorBoard可视化:projector_MNIST

    import os import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data from te ...

  3. 吴裕雄--天生自然 PHP开发学习:MySQL 预处理语句

    <?php $servername = "localhost"; $username = "root"; $password = "admin& ...

  4. JS—DOM操作

    节点分为三类: 1.元素节点:标签<div></div> 2.文本节点:标签内的纯文本. 3.属性节点:标签内的属性,id或class 查找元素: getElementById ...

  5. 分布式场景下Kafka消息顺序性的思考

    如果业务中,对于kafka发送消息异步消费的场景,在业务上需要实现在消费时实现顺序消费, 利用kafka在partition内消息有序的特点,消息消费时的有序性. 1.在发送消息时,通过指定parti ...

  6. 6.docker container

    1. 什么是container 通过 image 创建 (copy得到的) 在 image layer (在image 层) 上 增加了一层 container layer (container 层 ...

  7. Python笔记_第一篇_面向过程_第一部分_5.Python数据类型之元组类型(tuple)

    元组!在Python中元组是属于列表的一种延伸,也是一种有序集合,成为一种只读列表,即数据可以被查找,不能被修改,列表的切片操作同样适用于元组. 特点:1. 与列表非常相似. 2. 一旦初始化就不能修 ...

  8. PHP 5.3 新特性

    1 PHP 5.3中的新特性 1.1 支持命名空间 (Namespace) 毫无疑问,命名空间是PHP5.3所带来的最重要的新特性. 在PHP5.3中,则只需要指定不同的命名空间即可,命名空间的分隔符 ...

  9. 微信小程序生成海报保存图片到相册小测试

    test.wxml <canvas style="width:{{imageWidth}}px;height:{{imageHeight}}px;" canvas-id=&q ...

  10. spring boot pom demo

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...