zoukankan      html  css  js  c++  java
  • poj 2728【Desert King】

    我之前也没有搞过01规划,但是之前做过3621,3621这道题也用到了01规划,虽然我还是不太理解01规划,但是3621题解的推导过程给了我启示……

    1. ∑cost[i]/∑len[i] <= ans
    2. ∑cost[i] <= ans * ∑len[i]
    3. ∑(cost[i] - ans * len[i]) <= 0

    当和小于0时说明ans需变小

    还有这一题目很自然就要用prim,题目只给了点的坐标和高度,而且点也不算太多,如果用Krustral要存的边会很多……而且第一个城市是首都,(there will be only one way to connect each village to the capital),从第一个点开始就很自然了……而且3621很坑爹的输出让我WA了N次,还是参考别人的代码改成%.2f的,才A,这一题很自然就只用%.3f了,可是这为什么啊?

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 
      5 const int maxN = 1000+10;
      6 const double eps = 1e-6;
      7 int n;
      8 int x[maxN],y[maxN],h[maxN];
      9 double dist[maxN][maxN];
     10 int height[maxN][maxN];
     11 double d[maxN];
     12 bool vis[maxN];
     13 
     14 double dis(int i,int j)
     15 {
     16     return sqrt(1.0*(x[i] - x[j])*(x[i] - x[j]) + 1.0 * (y[i] - y[j]) * (y[i] - y[j]));
     17 }
     18 
     19 int heig(int i,int j)
     20 {
     21     int ans = h[i] - h[j];
     22     return ans < 0?(-ans):ans;
     23 }
     24 
     25 double prim(double mid)
     26 {
     27     memset(vis,false,sizeof(vis));
     28     for(int i = 0;i < n;i ++)
     29     {
     30         d[i] = height[0][i] - mid*dist[0][i];
     31     }
     32     vis[0] = true;
     33    double sum = 0;
     34     for(int i = 1;i < n;i ++)
     35     {
     36         double minn = 1000000000+1000000;
     37         int k = 0;
     38         for(int j = 1;j < n;j ++)
     39         {
     40             if(!vis[j] && minn > d[j])
     41             {
     42                 minn = d[k = j];
     43             }
     44         }
     45 
     46        sum += minn;
     47         vis[k] = true;
     48         for(int j = 1;j < n;j ++)
     49         {
     50             double jj = height[k][j] - mid*dist[k][j];
     51             if(!vis[j] && d[j] > jj)
     52             {
     53                 d[j] = jj;
     54             }
     55         }
     56     }
     57 
     58     return sum;
     59 }
     60 
     61 int main()
     62 {
     63     while(scanf("%d",&n),n)
     64     {
     65         for(int i = 0;i < n;i ++)
     66         {
     67             scanf("%d%d%d",&x[i],&y[i],&h[i]);
     68         }
     69 
     70         for(int i = 0;i < n-1;i ++)
     71         {
     72             dist[i][i] = 0;
     73             height[i][i] = 0;
     74             for(int j = i + 1;j < n;j ++)
     75             {
     76                 dist[i][j] = dist[j][i] = dis(i,j);
     77                 height[i][j] = height[j][i] = heig(i,j);
     78             }
     79         }
     80         dist[n-1][n-1] = 0;
     81         height[n-1][n-1] = 0;
     82 
     83         double left = 0;
     84         double right = 100000;
     85         while(right - left > eps)
     86         {
     87             double mid = (left + right) / 2;
     88             if(prim(mid) < 0)
     89             {
     90                 right = mid;
     91             }
     92             else
     93             {
     94                 left = mid;
     95             }
     96         }
     97       
     98        printf("%.3f\n",left);
     99     }
    100 
    101     return 0;
    102 }
  • 相关阅读:
    ****阿里云使用+快速运维总结(不断更新)
    Linux 标准目录结构
    linux awk命令
    反射型 DDoS 攻击的原理和防范措施
    容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?
    谈谈数据库的跨机房容灾-网易云
    前端 支持 超大上G,多附件上传
    java 支持 超大上G,多附件上传讨论
    java 支持 超大上G,多附件上传分享
    java 支持 超大上G,多附件上传功能
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2663525.html
Copyright © 2011-2022 走看看