zoukankan      html  css  js  c++  java
  • 最小割

    最优比率生成树

    poj 2728    Desert King     http://poj.org/problem?id=2728

    题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,

             建造水管距离为坐标之间的欧几里德距离(好象是叫欧几里德距离吧),费用为海拔之差

             现在要求方案使得费用与距离的比值最小

             http://www.cppblog.com/jh818012/articles/167743.html

     1 #include<iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 using namespace std;
     6 #define INF 10000000
     7 int x[1002],y[1002],h[1002],n;
     8 double  dis[1002][1002],high[1002][1002],d[1002],vis[1002];
     9 
    10 double prim(double r)
    11 {
    12     int i,j;
    13     for(i=2;i<=n;i++)
    14         d[i]=high[1][i]-dis[1][i]*r;
    15     memset(vis,0,sizeof(vis));
    16     vis[1]=1;
    17     double p=0;
    18     for(i=1;i<n;i++)
    19     {
    20         double minn=INF;
    21         int v;
    22         for(j=1;j<=n;j++)
    23             if(!vis[j]&&minn>d[j])
    24             {
    25                 minn=d[j];
    26                 v=j;
    27             }
    28             p+=minn;
    29             vis[v]=1;
    30         
    31             for(j=1;j<=n;j++)
    32                 if(!vis[j])
    33                     if(d[j]>high[v][j]-dis[v][j]*r)
    34                         d[j]=high[v][j]-dis[v][j]*r;
    35         
    36     }
    37     return p;
    38 }
    39 
    40 int main()
    41 {
    42     int i,j,m,t;
    43     while(scanf("%d",&n))
    44     {
    45     
    46         if(n==0)
    47             break;
    48         double max=0.0;
    49         for(i=1;i<=n;i++)    
    50             scanf("%d%d%d",&x[i],&y[i],&h[i]);    
    51     
    52         for(i=1;i<=n;i++)
    53             for(j=i+1;j<=n;j++)
    54                 {
    55                     double b;
    56                     b=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
    57                     dis[i][j]=dis[j][i]=sqrt(b);
    58                     high[i][j]=high[j][i]=abs(h[i]-h[j]);
    59                     if(max<high[i][j]/dis[i][j])
    60                         max=high[i][j]/dis[i][j];
    61                 }
    62             //printf("max  %lf
    ",max);
    63                 double right=max,left=0.0, ans,mid;
    64                 while(right>left)
    65                 {
    66                     mid=(right+left)/2;
    67                     ans=prim(mid);
    68                     if(fabs(ans-0.0)<0.0005)
    69                         break;
    70                     else if(ans>=0.0005)
    71                         left=mid;
    72                     else right=mid;
    73                 }
    74                 printf("%.3lf
    ",mid);
    75     }
    76     return 0;
    77 }
    78                 
    79                     
    View Code
  • 相关阅读:
    朱刘算法---有向图的最小生成树
    527D Clique Problem 判断一维线段没有两辆相交的最大线段数量
    Tex中的引号
    DAY 96 flask05
    DAY 95 flask04
    DAY 94 flask03
    DAY 93 flask02
    DAY 92 flask01
    DAY 91 爬虫05
    DAY 90 爬虫04
  • 原文地址:https://www.cnblogs.com/assult/p/3329230.html
Copyright © 2011-2022 走看看