样例(无向图):
1.Prim算法
#include <iostream>
#define MaxVertex 100
#define INF 100000
typedef int Vertex;
typedef class MatrixGraph* MGraph;
using namespace std;
class MatrixGraph
{
public:
void Build(MGraph Graph);
Vertex FindMin(MGraph Graph);
void IniPrim(MGraph Graph,Vertex s);//初始化
void Prim(MGraph Graph,Vertex s);
void Output(MGraph Graph,Vertex s);
private:
int Nv;
int Ne;
int G[MaxVertex][MaxVertex];
int parent[MaxVertex];//并查集
int dist[MaxVertex];//距离
int sum;//权重和
Vertex MST[MaxVertex];//最小生成树
};
//初始化
void MatrixGraph::Build(MGraph Graph)
{
Vertex v1, v2;
int weight;
Graph->sum = 0;
cout << "输入顶点数:";
cin >> Graph->Nv;
for (Vertex v = 1; v <= Graph->Nv; v++)
{
for (Vertex w = 1; w <= Graph->Nv; w++)//初始化图下标1开始
Graph->G[v][w] = 0;
Graph->dist[v] = INF;//初始化距离无穷大
Graph->parent[v] = -1;//初始化并查集
}
cout << "输入边数:";
cin >> Graph->Ne;
cout << "输入边<v1,v2>和相应权重:"<<endl;
for (Vertex v = 1; v <= Graph->Ne; v++)
{
cin >> v1 >> v2 >> weight;
Graph->G[v1][v2] = weight;//无向边
Graph->G[v2][v1] = weight;
}
}
//prim算法前初始化
void MatrixGraph::IniPrim(MGraph Graph, Vertex s)
{
Graph->MST[1] = s;//s为根节点
Graph->dist[s] = 0;//树根节点距离初始化
for (Vertex v = 1; v <= Graph->Nv; v++)//初始化s连接的所有边
{
if (Graph->G[s][v])
{
Graph->dist[v] = Graph->G[s][v];//更新v到根节点的距离
Graph->parent[v] = s;//更新s作为父节点
}
}
}
//查找图中还存在的最小dist,返回顶点
Vertex MatrixGraph::FindMin(MGraph Graph)
{
int min=INF;
Vertex v=-1;
for (Vertex i = 1; i <= Graph -> Nv; i++)
{
if (Graph->dist[i] && Graph->dist[i] < min)
{
min = Graph->dist[i];
v = i;//记录最小顶点
}
}
return v;
}
//prim算法
void MatrixGraph::Prim(MGraph Graph,Vertex s)
{
int i = 1;
IniPrim(Graph, s);
while (1)
{
Vertex v = FindMin(Graph);
if (v == -1)
break;
Graph->sum += Graph->dist[v];
i++;
Graph->MST[i] = v;//找到的顶点入树
Graph->dist[v] = 0;//表示图中该顶点已删除
for (Vertex w = 1; w <= Graph->Nv; w++)
{
if (Graph->G[v][w] && Graph->dist[w]&&Graph->dist[w] != 0 )//找到邻接点,路径存在且该点未被删除
{
if (Graph->G[v][w] < Graph->dist[w])//更新邻接点w信息
{
Graph->dist[w] = Graph->G[v][w];
Graph->parent[w] = v;//v为父节点
}
}
}
}
if (i < Graph->Nv)//收录进去的结点不到顶点个数
{
*Graph->MST = NULL;
}
}
//输出
void MatrixGraph::Output(MGraph Graph,Vertex s)
{
if (!*Graph->MST)
{
cout << "图不连通,最小生成树不存在";
}
else
{
cout << "被收录的顺序:"<<endl;
for (int i = 1; i <= Graph->Nv; i++)
cout << Graph->MST[i] << " ";
cout << endl;
cout << "权重和为:" << Graph->sum << endl;
cout << "该生成树为:"<<endl;
for (Vertex v = 1; v <= Graph->Nv; v++)
{
if (Graph->parent[v] == -1)
Graph->parent[v] = s;
cout << v << "--" << Graph->parent[v] << endl;
}
}
}
int main()
{
Vertex s;
MatrixGraph MG;
MGraph Graph = new MatrixGraph;
MG.Build(Graph);
cout << "设置生成树的顶点:";
cin >> s;
MG.Prim(Graph, s);
MG.Output(Graph,s);
return 0;
}
运行:
2.Kruskal算法
#include <iostream>
#define MaxVertex 100
#define INF 100000
typedef class MGraph* Graph;
typedef int Vertex;
using namespace std;
class Edge
{
public:
int v1, v2;
int weight;
int E[MaxVertex];//存边
};
class MGraph:public Edge
{
public:
void Build(Graph Gra);
int FindMin(Graph Gra);
Vertex Find(Graph Gra, Vertex v);
bool Union(Graph Gra, Vertex v, Vertex w);
void Kruskal(Graph Gra);
void Output(Graph Gra);
private:
int G[MaxVertex][MaxVertex];
int parent[MaxVertex];//并查集
int MST[MaxVertex];//最小生成树
int sum;//权重和
int Nv;
int Ne;
};
//初始化
void MGraph::Build(Graph Gra)
{
Vertex v1, v2;
int weight;
Gra->sum = 0;
cout << "输入顶点数:";
cin >> Gra->Nv;
for (Vertex v = 1; v <= Gra->Nv; v++)
{
for (Vertex w = 1; w <= Gra->Nv; w++)
Gra->G[v][w] = 0;
Gra->parent[v] = -1;
}
cout << "输入边数:";
cin >> Gra->Ne;
cout << "输入边<v1,v2>和相应权重:"<<endl;
for (Vertex v = 1; v <= Gra->Ne; v++)
{
cin >> v1 >> v2 >> weight;
Gra->weight = weight;
Gra->E[v] = weight;
Gra->G[v1][v2] = weight;//无向边
Gra->G[v2][v1] = weight;
}
}
//找出已知边里最小的,删除并返回最小
int MGraph::FindMin(Graph Gra)
{
Vertex v, w;
int min = INF;//无穷大
for (v = 1; v <= Gra->Nv-1; v++)//无边图只扫描一个对角,这里取右上角
for(w=v+1;w<=Gra->Nv;w++)
{
if (Gra->G[v][w] < min&&Gra->G[v][w]!=0)
{
min = Gra->G[v][w];
Gra->v1 = v;
Gra->v2 = w;
}
}
return min;
}
//并查集查找操作
Vertex MGraph::Find(Graph Gra, Vertex v)
{
if (Gra->parent[v] < 0)
return v;
else
return Gra->parent[v] = Find(Gra, Gra->parent[v]);
}
//并查集并操作
bool MGraph::Union(Graph Gra, Vertex v, Vertex w)
{
v = Find(Gra, v);
w = Find(Gra, w);
if (v!= w)
{
if (Gra->parent[v] < Gra->parent[w]) {
Gra->parent[v] += Gra->parent[w];
Gra->parent[w] = v;
}
else {
Gra->parent[w] += Gra->parent[v];
Gra->parent[v] = w;
}
return true;
}
else
return false;
}
//Kruskal算法
void MGraph::Kruskal(Graph Gra)
{
int i=0;//记录树结点
int E;
Gra->MST[MaxVertex] = {};//树开始为空
while (i < Gra->Nv - 1 && FindMin(Gra) != INF)//树结点小于Nv-1,且还存在边
{
E = FindMin(Gra);
Gra->G[Gra->v1][Gra->v2] = INF;//相当于删除
if (Union(Gra,Gra->v1,Gra->v2))//不构成回路
{
i++;
Gra->MST[i] = E;//入树
Gra->sum += E;
}
else;//无视这条边
}
if (i < Gra->Nv - 1)
*Gra->MST = NULL;
}
//输出
void MGraph::Output(Graph Gra)
{
if (*Gra->MST == NULL)
{
cout << "该最小生成树不存在" << endl;
}
else
{
cout << "被收录顺序:"<<endl;
for (int i = 1; i <= Gra->Nv - 1; i++)
cout << Gra->MST[i] << " ";
cout << endl;
cout << "权重和:"<<Gra->sum<<endl;
cout << "生成树:" << endl;
for (Vertex v = 1; v <= Gra->Nv; v++)
{
cout << v << "--" << Gra->parent[v]<<endl;
}
}
}
int main()
{
MGraph MG;
Graph Gra = new MGraph;
MG.Build(Gra);
MG.Kruskal(Gra);
MG.Output(Gra);
delete Gra;
return 0;
}
运行: