• 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 }

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

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

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

  • 相关阅读:
    TCP/IP 13学习笔记
    代码注入的三种方法
    一个简单的GTK的例子程序
    打印同样一个数据,竟然出现不同的结果,解决方法。
    解决multiple definition of的方法
    anjuta的安装、配置以及第一个hello程序
    rhythmbox中文乱码的解决方法
    Windows 和 Linux开发工具对比
    debian(包括ubuntu)命令行下的中文支持
    如何解决warning: no newline at end of file?
  • 原文地址:https://www.cnblogs.com/sasuke-/p/5222467.html
Copyright © 2020-2023  润新知