zoukankan      html  css  js  c++  java
  • 管道问题(prim)

           

    Description

    Water can flow around, does not it? And it can also flow along a tunnel until it become stable. A certain amount of water could be held by some length of tunnel, so the amount of water in the tunnels is related to the length of tunnels. Here goes the problem that you are given some coordinates of vertexes. All you have to do is to connect all the vertexes with tunnels, can you find a way to connect all these vertexes so that the mount of water in these tunnels is minimized.

    Input

    The input contains multiple cases. Ease case begins with a line with an integer N (0<=N<=100), which is the number of vertexes you need to connect. The next N lines each contains two real numbers, the coordinates of vertexes. N=0 indicates the end of input.

    Output

    For each test case print the minimum of water you need, rounded to 2 decimal places.

    Sample Input

    5
    0 0
    0 3
    2 1
    1 1
    2.5 3.7
    0

    Sample Output

    7.25

     

          第一道最小生成树,用的是Prim。

     

    代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #define N 101
    #define MAX 0x7fffffff
    using namespace std;
    
    double map[N][N];//邻接矩阵 
    
    typedef struct point
    {
      double x,y;       
    } POINT; 
    POINT p[N];
    
    double distance(POINT p1,POINT p2)
    {
      return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));       
    }
    
    double prim(int n);
    
    int main()
    {
      double ans;
      int vex,i,j;
      
        while(scanf("%d",&vex)&& vex)
        {
            for(i = 0 ; i < vex ; ++i)
            scanf("%lf%lf",&p[i].x,&p[i].y);
            
            /*
              计算任意两点间的距离 
            */
            for(i = 0 ; i < vex ; ++i)
            for(j = i + 1 ; j < vex ; ++j)
              map[i][j] = map[j][i] = distance(p[i],p[j]);                        
            /*
              自己到自己的距离为0 
            */ 
            for(i = 0 ; i < vex ; ++i)
              map[i][i] = 0;
            
            ans = prim(vex);
         
            printf("%.2lf\n",ans);
        }   
        
      system("pause");
      return 0;    
    }
    
    double prim(int n)
    {
      double lowcost[N];//存放各点到第 0个点的最小代价 
      double sum;
      int vexset[N];//标记最小生成树中的点,1表示在,0表示不在 
      int v,i,j;
      sum = 0;
        
        for(i = 1 ;i<n ; ++i)
        {
           lowcost[i] = map[0][i];
           vexset[i] = 0 ;      
        }       
        
        vexset[0] = 1;//首先把第0号点加入 
        
          for(i = 0 ; i < n -1; ++i)   
          {
              /*
                找出离最小生成树 “最近 ”的点 v 
              */  
              for(v = -1,j = 1 ; j < n ; ++j)//j 从1开始,0早已加入 
              {
                 /* 以前是单独声明一个变量来比较,这样多了一个语句
                     用 v = -1就 可以少一个语句,因为是for()循环,
                     所以 大大提高效率 
                 */   
                 if(!vexset[j] && (v == -1 ||lowcost[j]< lowcost[v]))
                    v = j ; 
              }     
             
              vexset[v] = 1;//v 新加入 
             /*
               权值相加 
             */ 
              sum += lowcost[v];    
            
              /*
                以新加入的点 v 为起点更新 各点到 0点 的最小代价 
              */
              for(j = 0 ; j < n ; ++j)
              {
                  if( !vexset[j] && map[v][j] < lowcost[j])  
                  {
                    lowcost[j] = map[v][j];     
                  }  
              }        
          }
          return sum; 
    }
    
  • 相关阅读:
    闭区间上的连续函数必定是一致连续的
    利用开区间覆盖的约简给出$\bf{Lindelöf}$覆盖定理的一个新证明
    $\mathbf{R}^n$中的紧集是闭有界集
    $\mathbf{R}^n$中的紧集是闭有界集
    陶哲轩实分析 习题10.2.7 导函数有界的函数一致连续
    $\mathbf{R}$上的离散点集是至多可数集
    利用开区间覆盖的约简给出$\bf{Lindelöf}$覆盖定理的一个新证明
    闭区间上的连续函数必定是一致连续的
    $\mathbf{R}$上的离散点集是至多可数集
    利用开区间覆盖的约简给出有限覆盖定理的一个新证明
  • 原文地址:https://www.cnblogs.com/HpuAcmer/p/2439638.html
Copyright © 2011-2022 走看看