zoukankan      html  css  js  c++  java
  • POJ 2728 二分+最小生成树

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

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

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

      1 #include <iostream>
      2 
      3 #include <string>
      4 
      5 #include <cstdio>
      6 
      7 #include <cstring>
      8 
      9 #include <cstdlib>
     10 
     11 #include <algorithm>
     12 
     13 #include <cmath>
     14 
     15 #define MAXN 1005
     16 
     17 #define INF 1000000000
     18 
     19 #define eps 1e-7
     20 
     21 using namespace std;
     22 
     23 int n;
     24 
     25 double Edge[MAXN][MAXN], lowcost[MAXN];
     26 
     27 int nearvex[MAXN];
     28 
     29 struct Point
     30 
     31 {
     32 
     33     int x, y, z;
     34 
     35 }p[MAXN];
     36 
     37 double cal(int a, int b)
     38 
     39 {
     40 
     41     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));
     42 
     43 }
     44 
     45 double prim(int src, double l)
     46 
     47 {
     48 
     49     double cost = 0, len = 0;
     50 
     51     double sum = 0;
     52 
     53     for(int i = 1; i <= n; i++)
     54 
     55     {
     56 
     57         nearvex[i] = src;
     58 
     59         lowcost[i] = abs(p[src].z - p[i].z) - Edge[src][i] * l;
     60 
     61     }
     62 
     63     nearvex[src] = -1;
     64 
     65     for(int i = 1; i < n; i++)
     66 
     67     {
     68 
     69         double mi = INF;
     70 
     71         int v = -1;
     72 
     73         for(int j = 1; j <= n; j++)
     74 
     75             if(nearvex[j] != -1 && lowcost[j] < mi)
     76 
     77             {
     78 
     79                 v = j;
     80 
     81                 mi = lowcost[j];
     82 
     83             }
     84 
     85         if(v != -1)
     86 
     87         {
     88 
     89             cost += abs(p[nearvex[v]].z - p[v].z);
     90 
     91             len += Edge[nearvex[v]][v];
     92 
     93             nearvex[v] = -1;
     94 
     95             sum += lowcost[v];
     96 
     97             for(int j = 1; j <= n; j++)
     98 
     99             {
    100 
    101                 double tmp = abs(p[v].z - p[j].z) - Edge[v][j] * l;
    102 
    103                 if(nearvex[j] != -1 && tmp < lowcost[j])
    104 
    105                 {
    106 
    107                     lowcost[j] = tmp;
    108 
    109                     nearvex[j] = v;
    110 
    111                 }
    112 
    113             }
    114 
    115         }
    116 
    117     }
    118 
    119     return sum;
    120 
    121 }
    122 
    123 int main()
    124 
    125 {
    126 
    127     while(scanf("%d", &n) != EOF && n)
    128 
    129     {
    130 
    131         for(int i = 1; i <= n; i++)
    132 
    133             scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].z);
    134 
    135         for(int i = 1; i <= n; i++)
    136 
    137             for(int j = 1; j <= n; j++)
    138 
    139                 Edge[i][j] = cal(i, j);
    140 
    141         double low = 0, high = 10.0;             //其实二分20多次已经很足够了
    142 
    143         double l = 0.0, r = 100.0, mid;
    144 
    145         while(r - l > eps)
    146 
    147         {
    148 
    149             mid = (l + r) / 2;
    150 
    151             if(prim(1, mid) >= 0) l = mid;
    152 
    153             else r = mid;
    154 
    155         }
    156 
    157         printf("%.3f
    ", r);
    158 
    159     }
    160 
    161     return 0;
    162 
    163 }
    View Code
  • 相关阅读:
    C#之纯数字判断
    C#之仿魔兽登录
    jQuery考试之错题分析
    初学jQuery之jQuery虚假购物车-------与真实数据无关
    Jquery中绑定事件的异同
    总结java基础
    初学jQuery之jQuery事件与动画
    初学jQuery之jQuery选择器
    JavaScript 实现复制到剪贴板的总结
    IE和其他浏览器的表现差异:盒子间的空隙,图片变形,justify-content无效
  • 原文地址:https://www.cnblogs.com/llllrj/p/9402294.html
Copyright © 2011-2022 走看看