实现prim算法

如下找出该图的最小生成树 

prim算法是求解该类问题的一种经典算法

Prim算法的基本思路:
将图中的所有的顶点分为两类:树顶点(已经被选入生成树的顶点)和非树顶点(还未被选入生成树的顶点)。首先选择任意一个顶点加入生成树,接下来要找出一条边添加到生成树,

这需要枚举每一个树顶点到每一个非树顶点所有的边,然后找到最短边加入到生成树。依次,重复操作n-1次,直到将所有顶点都加入生成树中。

算法实现如下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 void Prim(int n,int c[ ][100])
 4 {
 5     int  lowcost[100];//各非树顶点到树顶点集的最短路径
 6     int closet[100];//非树顶点到树顶点集的最小边中相对的顶点
 7     bool foot[n+1];//表示是否已经为树顶点,初始为false
 8     memset(lowcost,0,sizeof(lowcost));
 9     memset(closet,0,sizeof(closet));
10     foot[1]=true;//假设先把1作为初始顶点
11     for(int i=2;i<=n;i++){//假设从节点一开始
12         foot[i]=false;
13         closet[i]=1;
14         lowcost[i]=c[1][i];
15     }
16     for(int i=1;i<n;i++){
17         int  min=99999;
18         int j=1;
19         for(int k=2;k<=n;k++){//计算非树顶点到树顶点集的最短路径,并把对应顶点记为j
20             if((lowcost[k]<min)&&(foot[k]==false)){
21                 min=lowcost[k];
22                 j=k;
23             }
24         }
25         cout <<"选边"<< "("<<closet[j] << "," <<j<<")" << endl;//把改变归为已选边,并把foot[j]设为true
26         foot[j]=true;
27         for(int k=2;k<=n;k++){//由于新的顶点加入树顶点,所以要更新非树顶点到树顶点集的最短路径lowcost[j],和对应的clost[j]
28             if((c[j][k]<lowcost[k])&&(foot[k]==false)){
29                 lowcost[k]=c[j][k];
30                 closet[k]=j;
31             }
32         }
33     }
34 
35 
36 }
37 int main()
38 {
39     cout << "请输入图的顶点数" << endl;
40     int n;
41     cin >>n;
42     cout << "请输入图的边数" << endl;
43     int m;
44     cin >> m;
45     cout << "请输入图的边的两个端点和边的长度" << endl;
46     int c[100][100];
47     for(int i=1;i<=n;i++){
48         for(int j=1;j<=n;j++){
49             c[i][j]=99999;
50         }
51     }
52     int i1,j,k;
53     for(int i=1;i<=m;i++){
54         cin >>i1 >> j >> k;
55         c[i1][j]=k;
56         c[j][i1]=k;
57     }
58     Prim(n,c);
59     return 0;
60 
61 }

运行结果如下

猜你喜欢

转载自www.cnblogs.com/henuliulei/p/9951778.html
今日推荐