Prim算法求最小生成树
Posted guoyujiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prim算法求最小生成树相关的知识,希望对你有一定的参考价值。
Prim算法: 采用贪婪算法,通过迭代逐步加入权重最小的边进行构造。
伪代码:
1,初始化U={u0},E为空集; //E是最小生成树的边集合,U是其顶点集合,选定构造最小生成树的出发点u0;
2,重复以下步骤直到U=V;
2.1 以顶点集U和顶点集V-U之间的所有边作为侯选边,从中寻找权值最小的边(u,v)
2.2 令U=U∪{v},E=E∪{(u,v)}
1 #include <iostream>
2 #include <vector>
3 #include <queue>
4 #include <string>
5 #include <climits>
6
7 using namespace std;
8
9 template<class T>
10 struct GraphNode
11 {
12 bool visited;
13 int index;
14 int weight;
15 T vertexName;
16 //自定义优先级:weight小的优先
17 friend bool operator<(GraphNode a, GraphNode b) {
18 return a.weight > b.weight;
19 }
20 };
21
22 template<class T>
23 class Graph
24 {
25 public:
26 Graph() {}
27 Graph(int * vertexArray, T * nameOfVertex, int numberOfVertex);
28
29 //Prim
30 void Prim(int source);
31
32 private:
33 int vertexNum, arcNum;
34 vector<vector<int>>adjacencyMatrix; //邻接矩阵
35 vector<GraphNode<T>>graphNodeArray; //顶点信息,只初始化index和vertexName
36 };
37
38
39 int main()
40 {
41 const int numofVertex = 7;
42 int cost[numofVertex][numofVertex] = {
43 { INT_MAX, 12 , 5 , 11 ,INT_MAX , INT_MAX ,INT_MAX },
44 { 12, INT_MAX , INT_MAX ,INT_MAX , 33 , INT_MAX ,INT_MAX },
45 { 5, INT_MAX , INT_MAX , 21 ,INT_MAX , 19 ,INT_MAX },
46 { 11, INT_MAX , 21 ,INT_MAX , 28 , 8 ,INT_MAX },
47 { INT_MAX, 33, INT_MAX , 28 ,INT_MAX , INT_MAX , 6 },
48 { INT_MAX, INT_MAX , 19 , 8 ,INT_MAX , INT_MAX , 16 },
49 { INT_MAX, INT_MAX , INT_MAX ,INT_MAX , 6 , 16 ,INT_MAX }
50 };
51 //初始化各顶点
52 string verName[numofVertex] = { "A","B","C","D","E","F","G" };
53 Graph<string>g(*cost, verName, numofVertex);
54
55 cout << "Prim算法执行结果:" << endl;
56 try {
57 g.Prim(0);
58 }
59 catch (...) {
60 cout << "算法执行失败" << endl;
61 }
62 system("pause");
63 return 0;
64 }
65
66 template<class T>
67 Graph<T>::Graph(int * vertexArray, T * nameOfVertex, int numberOfVertex)
68 {
69 vertexNum = numberOfVertex; //顶点数
70 arcNum = 0;
71 GraphNode<T> tempgraphNode;
72 for (int i = 0; i < vertexNum; i++)
73 {
74 tempgraphNode.index = i;
75 tempgraphNode.vertexName = nameOfVertex[i];
76 graphNodeArray.push_back(tempgraphNode);
77 }
78 //分配所需空间
79 adjacencyMatrix.resize(vertexNum, vector<int>(vertexNum));
80 for (int i = 0; i < vertexNum; i++)
81 for (int j = 0; j < vertexNum; j++)
82 adjacencyMatrix[i][j] = *(vertexArray + i*vertexNum + j);
83 }
84
85 template<class T>
86 void Graph<T>::Prim(int source)
87 {
88 int vertextNum = adjacencyMatrix.size();
89 if (source > vertexNum)
90 throw"位置";
91
92 vector<int>path(vertexNum);
93 priority_queue<GraphNode<T>>queue;
94 int minIndex;
95 graphNodeArray.resize(vertextNum); //重置足够空间
96
97 for (int i = 0; i < vertextNum; i++)
98 {
99 graphNodeArray[i].visited = false;
100 graphNodeArray[i].weight = INT_MAX;
101 path[i] = source; //记录U 集合双亲关系
102 }
103 graphNodeArray[source].weight = 0;
104 queue.push(graphNodeArray[source]);
105
106 while (!queue.empty())
107 {
108 GraphNode<T> tempGraphNode = queue.top();
109 queue.pop();
110 if (tempGraphNode.visited)
111 continue;
112 tempGraphNode.visited = true;
113 minIndex = tempGraphNode.index; //两个集合之间的权值最小边对应的V-U 中顶点的序号
114 for(int j=0; j<vertextNum; j++)
115 //两个集合之间的权值最小边对应的V-U中的顶点 的关联边入队
116 if (j != minIndex && !graphNodeArray[j].visited&&adjacencyMatrix[minIndex][j] < graphNodeArray[j].weight)
117 {
118 path[j] = minIndex;
119 graphNodeArray[j].weight = adjacencyMatrix[minIndex][j];
120 queue.push(graphNodeArray[j]); //边入队,顺便找到其在队中位置
121 }
122 }
123 for (int j = 0; j < vertextNum; j++)
124 {
125 int priorindex = path[j];
126 if (priorindex != j)
127 cout << graphNodeArray[priorindex].vertexName << "----" << graphNodeArray[j].vertexName << " ";
128 }
129 cout << endl;
130 }
参考前一篇: Kruskal
以上是关于Prim算法求最小生成树的主要内容,如果未能解决你的问题,请参考以下文章