• HDU 1863 畅通工程(Prim算法求解MST)


    题目:

    省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 

    Input测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 
    行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 
    Output对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。 
    Sample Input

    3 3
    1 2 1
    1 3 2
    2 3 4
    1 3
    2 3 2
    0 100

    Sample Output

    3
    ?
    题意描述:
    输入道路条数和城市数目
    计算并输出使任意两个村庄直接或者间接连通的最短距离
    解题思路:
    属于最小生成树问题,按照数据格式,使用Kruskal算法即可。
    代码实现:
     1 #include<stdio.h>
     2 #include<string.h>
     3 int e[110][110],book[110],dis[110];
     4 const int inf=99999999; 
     5 int main()
     6 {
     7     int n,m,min,t1,t2,t3,i,j,c,sum,k;
     8     while(scanf("%d%d",&m,&n), m != 0)//m为道路条数,n为村庄个数 
     9     {
    10         memset(e,0,sizeof(e));
    11         for(i=1;i<=n;i++)//初始化邻接矩阵 
    12         {
    13             for(j=1;j<=n;j++){
    14                 if(i==j)
    15                 e[i][j]=0;
    16                 else
    17                 e[i][j]=inf;
    18             }
    19         }
    20         for(i=1;i<=m;i++)
    21         {
    22             scanf("%d%d%d",&t1,&t2,&t3);
    23             e[t1][t2]=t3;
    24             e[t2][t1]=t3;
    25         }
    26         for(i=1;i<=n;i++)//初始化dis,存储距离生成树(仅有1顶点)到每个非树顶点的距离 
    27             dis[i]=e[1][i];
    28         memset(book,0,sizeof(book));
    29         book[1]=1;
    30         c=1;    
    31         sum=0;//sum初始化,当只有一个正确样例时注意多复制一下 
    32         
    33         while(c < n)//直到找到n-1条边 
    34         {
    35             min=inf;
    36             for(j=0,i=1;i<=n;i++)
    37             {//遍历每个定点,找到某个顶点没有被用过而且距离生成树又最近
    38                 if(book[i]==0 && dis[i] < min) 
    39                 {
    40                     min=dis[i]; 
    41                     j=i;
    42                 }
    43             }
    44             book[j]=1;//标记使用并计数,将其累加到sum上 
    45             c++;
    46             sum += dis[j];
    47             
    48             for(k=1;k<=n;k++)
    49             {//最后遍历所有边,以j为中间点更新dis数组中生成树到每一个非树顶点的距离 
    50                 if(book[k]==0 && dis[k] > e[j][k])
    51                     dis[k]=e[j][k];
    52             }
    53         }
    54         
    55         for(i=1;i<=n;i++){
    56             if(!book[i])
    57                 break;
    58         }
    59         if(i == n+1)
    60         printf("%d
    ",sum);
    61         else
    62         printf("?
    ");
    63     }
    64     return 0;
    65 }

    易错分析:

    1、注意数据输入,结点数在前还是边数在前

    2、当只有一个样例时,多出几组测试样例,想几个样例的时间跟罚时20分钟比起来要少的多,另外不影响情绪

  • 相关阅读:
    Integer Inquiry
    dfs求最短路径
    5.E
    5.H
    5.C
    5.A
    5.J
    POJ
    POJ
    POJ
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/7278243.html
Copyright © 2020-2023  润新知