最小生成树
注意:
该算法采用c++在类内实现,每个顶点用整数表示,权重用double类型数据,点用邻接矩阵表示,类名为Solution。
vector比数组方便一些,所以这里vector来代表数组。
类成员变量
int v;//点数量
vector<vector<double>>EdgeWeight;//点与点之间权值
vector<bool>marked;//标记点是否在最小生成树内
vector<vector<double>>answer;//最终最小生成树保存在这里
int Edges=0;//记录数内的边数(最小生成树完全形成时边数比点数少一个,初始化为0)
内成员函数
Solution(int size) {//构造函数
this->v = size;//确定点数
marked.resize(size, false);//最开始每个点都没有在树内,初始化每个点标记为false
EdgeWeight.resize(size);//初始化点的邻边集合
for (vector<double> &x : EdgeWeight) {//每两个点的权重都是初始化0
x.resize(size,0.0);
}
answers.resize(size);//同上
for (vector<double>& x : answers) {
x.resize(size, 0.0);
}
}
//---------------------------------------------------------------
void addEdge(int a, int b, double weight) {//添加邻边&&设置权重
EdgeWeight[a][b] = weight;
EdgeWeight[b][a] = weight;
}
//---------------------------------------------------------------
void start() {
marked[0] = true;// 开始先将0号点放入树中
double weight;
int i, j;
int x = 0, y = 0;
while (Edges != v - 1) {//当边数不等于点数-1就一直执行
//该局部变量weight用于找出最小权重的边(先将weight初始化为大一点的数,至少超过最大权重)
weight = 99999;
for (i = 0; i < v; i++) {
if (!marked[i]) {//未标记-->不在树中
for (j = 0; j < v; j++) {
if (marked[j]/*在树中*/ && EdgeWeight[i][j] != 0&&EdgeWeight[i][j]<weight) {
//若存在权值比weight的权值小边,就将该边的权值赋值给weight,并记录该边的两个点
weight = EdgeWeight[i][j];
x = i, y = j;
}
}
}
else {
continue;
}
}
marked[x] = marked[y] = true;//标记最小权值的边的点个点
answers[x][y] = EdgeWeight[x][y];//将权重赋值给answer
Edges++;//边数记录加1(与while循环相对应)
}
}
//---------------------------------------------------------------
void show1() {//输出添加边后的情况
for (vector<double>v : EdgeWeight) {
for (double x : v) {
cout << x << ' ';
}
cout << endl;
}
}
//---------------------------------------------------------------
void show2() {//输出最小生成树
for (vector<double>v : answers) {
for (double x : v) {
cout << x << ' ';
}
cout << endl;
}
}
全部代码加测试代码
#include<iostream>
#include<map>
#include<vector>
using namespace std;
class Solution {
public:
int v;
vector<vector<double>>EdgeWeight;//全部边以及权重
vector<vector<double>>answers;//最小生成树成员
vector<bool>marked;//标记是否在树上
int Edges = 0;
Solution(int size) {
this->v = size;
marked.resize(size, false);
EdgeWeight.resize(size);
for (vector<double> &x : EdgeWeight) {
x.resize(size,0.0);
}
answers.resize(size);
for (vector<double>& x : answers) {
x.resize(size, 0.0);
}
}
void addEdge(int a, int b, double weight) {
EdgeWeight[a][b] = weight;
EdgeWeight[b][a] = weight;
}
void start() {
marked[0] = true;
double weight;
int i, j;
int x = 0, y = 0;
while (Edges != v - 1) {
weight = 99999;
for (i = 0; i < v; i++) {
if (!marked[i]) {
for (j = 0; j < v; j++) {
if (marked[j] && EdgeWeight[i][j] != 0&&EdgeWeight[i][j]<weight) {
weight = EdgeWeight[i][j];
x = i, y = j;
}
}
}
else {
continue;
}
}
marked[x] = marked[y] = true;
answers[x][y] = EdgeWeight[x][y];
Edges++;
}
}
void show1() {
for (vector<double>v : EdgeWeight) {
for (double x : v) {
cout << x << ' ';
}
cout << endl;
}
}
void show2() {
for (vector<double>v : answers) {
for (double x : v) {
cout << x << ' ';
}
cout << endl;
}
}
};
int main() {
Solution s(6);
s.addEdge(0, 1, 3.0);
s.addEdge(1, 2, 1.0);
s.addEdge(2, 3, 2.0);
s.addEdge(0, 3, 7.0);
s.addEdge(0, 4, 4.0);
s.addEdge(4, 5, 3.0);
s.addEdge(2, 5, 8.0);
s.show1();
cout << "============" << endl;
s.start();
s.show2();
}