zoukankan      html  css  js  c++  java
  • HDU 1875 最小生成树prim算法

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #define MAX 0xffffffff            //定义一个最小生成树中不可能达到的值 
     7 const int qq=100+10;            // 点的上限 
     8 using namespace std;
     9 struct point{
    10     int x,y;
    11 }node[qq];            
    12 double lowcost[qq][qq];                // 邻接矩阵 
    13 int vis[qq];                        // 最小生成树的点集合vis数组 
    14 int n;
    15 double f(point a,point b)
    16 {
    17     return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0));
    18 }
    19 void build()
    20 {
    21     double len;
    22     for(int j,i=0;i<n;++i)
    23         for(j=i;j<n;++j){
    24             len=f(node[i],node[j]);        // 计算两点之间的距离也就是点与点的权值、 
    25             if(len>=10&&len<=1000)
    26                 lowcost[i][j]=lowcost[j][i]=(i==j)?0:len;
    27             else
    28                 lowcost[i][j]=lowcost[j][i]=MAX;        // 值为MAX 意味着这两点不连通、 
    29         }
    30 }
    31 void prim()
    32 {
    33     int k,t=n;
    34     double min,tot=0;
    35     vis[0]=0;            //初始点0进入最小生成树数组中、 
    36     while(--t){        
    37         min=MAX;
    38         for(int i=1;i<n;++i){
    39             if(vis[i]!=0&&lowcost[0][i]<min){        //lowcost[0]代表当前的最小生成树的最小权值数组、 
    40                 min=lowcost[0][i];                    //找到当前最小的权值并记录是哪一个点、 
    41                 k=i;
    42             }
    43         }
    44         if(min==MAX)    break;                        //如果最小权值都为MAX 也就是不连通也可以跳出循环了、 
    45         vis[k]=0;                                    // 点k进入最小生成树数组、 
    46         tot+=min;                //统计权值、 
    47         for(int i=1;i<n;++i)                        //因为加入了一个点到最小生成树中,所以要更新当前的最小权值数组、 
    48             if(vis[i]!=0&&lowcost[k][i]<lowcost[0][i])
    49                 lowcost[0][i]=lowcost[k][i];
    50     }
    51     if(t==0)    printf("%.1f
    ",tot*100);
    52     else        printf("oh!
    ");
    53 }
    54 int main()
    55 {
    56     int t;cin >> t;
    57     while(t--){
    58         memset(vis,1,sizeof(vis));        //清空标记数组、 
    59         scanf("%d",&n);
    60         for(int i=0;i<n;++i)
    61             scanf("%d%d",&node[i].x,&node[i].y);
    62         build();
    63         prim();
    64     }
    65 }

    刚做这题我模型没转换过来,以为只要把横坐标按从小到大排序,横坐标相同就按纵坐标从小到大排序然后然后从左到右从下道上连接各点就是最小生成树、

    - - 、 错的太离谱了,代码就不拿出来丢脸了

    题目设置的限制条件实际上就是不连通,这点想通了就好做了

  • 相关阅读:
    java 寒假作业
    java 搭积木
    java 移动距离
    java 垒骰子
    java 饮料换购
    java 牌型种数
    ONOS基础教程(QuickStart with a VM)
    Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
    PM2使用基本介绍
    nodejs项目部署
  • 原文地址:https://www.cnblogs.com/sasuke-/p/5222467.html
Copyright © 2011-2022 走看看