参考王道《2023年数据结构考研复习指导》
#include <iostream>
#define MaxVerTexNum 20
typedef char VertexType; // 顶点的数据类型
typedef int EdgeType; // 带权图中边上权值的数据类型
// 邻接矩阵存储图
typedef struct {
VertexType Vex[MaxVerTexNum]; // 顶点表
EdgeType Edge[MaxVerTexNum][MaxVerTexNum]; // 邻接矩阵,边表(-1代表无穷大)
int vexnum, arcnum; // 图的当前顶点数和边数/弧数
} MGraph;
void MiniSpanTree_Prim(MGraph G, int u);
void Visit(const MGraph& G, int u, int v);
int main() {
MGraph G = {
{'1', '2', '3', '4', '5', '6'},
{
{-1, 6, 1, 5, -1, -1},
{6, -1, 5, -1, 3, -1},
{1, 5, -1, 5, 6, 4},
{5, -1, 5, -1, -1, 2},
{-1, 3, 6, -1, -1, 6},
{-1, -1, 4, 2, 6, -1}
},
6, 10
};
MiniSpanTree_Prim(G, 0);
system("pause");
return 0;
}
// 从顶点u出发,构造最小生成树,并输出生成树的每条边
void MiniSpanTree_Prim(MGraph G, int u) {
struct {
int adjvex; // 顶点编号
int lowcost; // 从顶点adjvex到当前顶点的权值(为0代表已加入集合U)
}closedge[MaxVerTexNum]; // 求最小生成树时的辅助数组
for (int i = 0; i < G.vexnum; ++i) {
closedge[i].adjvex = u;
closedge[i].lowcost = G.Edge[u][i];
}
closedge[u].lowcost = 0; // 初始化,U = {u}
for (int i = 1; i < G.vexnum; ++i) { // 找n-1条边
int min = -1; // closedge数组中的最小权值
int v; // 下一个加入集合U的顶点
for (int j = 0; j < G.vexnum; j++) { // 找到closedge数组中的最小边
if (min == -1 && closedge[j].lowcost > 0) {
min = closedge[j].lowcost;
v = j;
}
if (min != -1 && closedge[j].lowcost > 0 && closedge[j].lowcost < min) {
min = closedge[j].lowcost;
v = j;
}
}
closedge[v].lowcost = 0; // 将顶点v纳入集合U
int u = closedge[v].adjvex;
Visit(G, u, v);
for (int j = 0; j < G.vexnum; ++j) { // 在顶点v并入U之后,更新closedge[i]
if (closedge[j].lowcost != 0 && G.Edge[v][j] > 0) {
if (closedge[j].lowcost == -1)
{
closedge[j].adjvex = v;
closedge[j].lowcost = G.Edge[v][j];
}
else if (closedge[j].lowcost != -1 && G.Edge[v][j] < closedge[j].lowcost) {
closedge[j].adjvex = v;
closedge[j].lowcost = G.Edge[v][j];
}
}
}
}
}
void Visit(const MGraph& G, int u, int v) {
std::cout << G.Vex[u] << " -> " << G.Vex[v] << " : " << G.Edge[u][v] << std::endl;
}