首先,图论中的最小生成树问题就是给出一个大小为n*m邻接矩阵或者n个顶点m条边(包含每条边路径花费)的数据,让我们计算使得这n个顶点直接或间接联通所需要的最小花费。

  其次,所给的数据分为稀疏图和稠密图,对于一个图,理论上n个顶点可以有n*(n-1)条边,如果该图中存在的边数m远小于n*(n-1),可以称之为稀疏图,如果该图中存在的边数m接近n*(n-1),可以称之为稠密图。

  接下来,先总结一下prim算法。我们将图中所有的顶点分为两类:树顶点(已被选入生成树的顶点)和非树顶点(还未被选入生成树的顶点)。首先选择任意一个顶点加入生成树。接下来要找出一条边添加到生成树,这需要枚举每一个树顶点到每一个非树顶点所有的边,然后找到最短边加入到生成树。按照此方法重复n-1次,直到将所有顶点都加入到生成树中。

  prim算法模板题:http://hihocoder.com/problemset/problem/1097

  AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 int e[1100][1100],book[1100],dis[1100];        // 顶点数n<=1000 
 4 const int inf=99999999;                        
 5 int main()
 6 {
 7     int n,i,j,k,c,sum,min;
 8     while(scanf("%d",&n) != EOF)
 9     {
10         for(i=1;i<=n;i++)
11             for(j=1;j<=n;j++)
12                 scanf("%d",&e[i][j]);        
13         for(i=1;i<=n;i++)
14             dis[i]=e[1][i];
15         
16         memset(book,0,sizeof(book));
17         book[1]=1;
18         c=1;
19         sum=0;
20         while(c < n)
21         {
22             min=inf;
23             for(j=0,i=1;i<=n;i++)
24             {
25                 if(!book[i] && dis[i] < min) //注意是且的关系,该点没有被访问过而且距离生成树最近 
26                 {
27                     min=dis[i];
28                     j=i;
29                 }
30             }
31             book[j]=1;                        //标记该点被访问过 
32             c++;                            //计加入的顶点数 
33             sum += dis[j];                    //累计花费 
34             for(k=1;k<=n;k++)                //更新生成树到各各非树顶点的距离 
35             {
36                 if(!book[k] && dis[k] > e[j][k])
37                     dis[k]=e[j][k];
38             }
39          }
40          printf("%d\n",sum);
41     } 
42     return 0;
43 }
View Code

相关文章:

  • 2022-12-23
  • 2021-07-27
  • 2022-12-23
  • 2022-12-23
  • 2021-07-01
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-02-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-30
相关资源
相似解决方案