C++Prim算法求最小生成树
MGraph.h
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
constexpr auto Infinity = 63353;
class MGraph {
public:
MGraph() = default;
~MGraph() = default;
void CreateMGraph() {
cout << "Please set the number of vertexes:";
cin >> this->NumVertexes;
for (int i = 0;i < NumVertexes;++i) {
cout << "Please set data for this vertex:";
string str;
cin >> str;
Vertexes.push_back(str);
}
arc.resize(NumVertexes);//set the number of lines
for (int i = 0;i < NumVertexes;++i) {
arc[i].resize(NumVertexes);//set the number colomns
for (int j = 0;j < NumVertexes;++j) {
if (i == j) arc[i][j] = 0;
else arc[i][j] = Infinity;
}
}//Init MGraph's elemts
cout << "Please set the number of edges:";
cin >> this->NumEdges;
for (int i = 0;i < NumEdges;++i) {
cout << "Please enter the start and end of an edge,and weight:";
int start, end, weight;
cin >> start >> end >> weight;
arc[start][end] = weight;
arc[end][start] = weight;
}
}
void DFSTraverse() {
for (int i = 0;i < NumVertexes;++i) visited.push_back(false);
for (int i = 0;i < NumVertexes;++i) {
if (!visited[i]) dfs(i);
}
}
private:
void dfs(int index) {
visited[index] = true;
cout << Vertexes[index] << " ";
for (int i = 0;i < NumVertexes;++i) {
if (arc[index][i] != Infinity && index != i && !visited[i]) {
dfs(i);
}
}
}
friend class Prim;
private:
int NumVertexes = 0;
int NumEdges = 0;
vector<string>Vertexes;
vector<vector<int>>arc;
vector<bool>visited;
};
Prim.h
#pragma once
#include<iostream>
#include<vector>
#include"MGraph.h"
using namespace std;
class Prim {
public:
Prim(MGraph&graph):M(graph) {
for (int i = 0;i < M.NumVertexes;++i) visited.push_back(false);
for (int i = 0;i < M.NumVertexes - 1;++i) lowest.push_back(Infinity);
}
~Prim() = default;
void PrimAlgorithm(int &begin) {
visited.at(begin) = true;
int numlowest = 0;
while (true) {
int flag = 0;
for (int i = 0;i < M.NumVertexes;++i) {
if (visited[i]) {
for (int j = 0;j < M.NumVertexes;++j) {
if (i != j && M.arc[i][j] < lowest[numlowest] && !visited[j]) {
lowest[numlowest] = M.arc[i][j];
flag = j;
}
}
}
}
visited[flag] = true;
numlowest++;
if (numlowest == M.NumVertexes - 1) break;
}
}
void ShowLowest() {
int sum = 0;
for (auto x : lowest) {
cout << x << " ";
sum += x;
}
cout << endl;
cout << "Lowest:" << sum << endl;
}
private:
vector<bool>visited;
vector<int>lowest;
MGraph& M;
};
Prim算法原理:
1)以某一个点开始,寻找当前该点可以访问的所有的边;
2)在已经寻找的边中发现最小边,这个边必须有一个点还没有访问过,将还没有访问的点加入我们的集合,记录添加的边;
3)寻找当前集合可以访问的所有边,重复2的过程,直到没有新的点可以加入;
4)此时由所有边构成的树即为最小生成树。