#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define MaxVertexNum 100 // 顶点数目的最大值
typedef char VertexType; // 顶点的数据类型
typedef int EdgeType; // 整数表示权值
typedef struct{
VertexType Vex[MaxVertexNum]; // 顶点表
EdgeType Edge[MaxVertexNum][MaxVertexNum]; // 邻接矩阵(二维数组),边表
int vexnum, arcnum; // 图的当前顶点数和弧数
}MGraph;
void CreateGraph(MGraph *g){
int start;
int end; // end---------->start
int weight;
printf("请输入顶点数和边数");
cin >> g->vexnum >> g->arcnum;
for (int i = 0; i < g->vexnum; ++i){ // 初始化顶点表
printf("请输入第%d个顶点的值(字符):", i);
cin >> g->Vex[i];
}
for (int i = 0; i < g->vexnum; ++i){
for (int j = 0; j < g->vexnum; ++j){
g->Edge[i][j] = 65535; // Int最大值,代表无连接
}
}
for (int i = 0; i < g->arcnum / 2; ++i){
printf("请输入第%d段弧(i j)和权值:", i);
cin >> end >> start >> weight;
g->Edge[end][start] = weight;
g->Edge[start][end] = weight;
}
}
void MiniSpanTree_Prim(MGraph *g){
int min;
int adjvex[MaxVertexNum]; // 保存邻接顶点下标的数组
int lowcost[MaxVertexNum]; // 记录当前生成树到剩余顶点的最小权值
lowcost[0] = 0; // 将0号顶点加入生成树
adjvex[0] = 0; // 由于刚开始生成树只有一个顶点不存在边,将邻接顶点的值都设为0
for (int i = 1; i < g->vexnum; ++i){
lowcost[i] = g->Edge[0][i]; // 将与下标未0的顶点右边的权值存入Lowcost数组
adjvex[i] = 0;
}
// 算法核心
for (int i = 1; i < g->vexnum; ++i){
min = 65536; // 因为要找最小值,不妨先设取一个最大的值来比较
int k = 0; // 找出lowcast最小的,最小权值给min,下标给k
int j = 0;
while (j < g->vexnum){
if (lowcost[j] != 0 && lowcost[j] < min){ // 条件:不在生成树中的顶点而且权值更小的
min = lowcost[j]; // 更新更小的值
k = j; // 下标赋值给k
}
j++; // 再看看下一个点
}
printf("(%d->%d)", adjvex[k], k); // 打印权值最小的边
lowcost[k] = 0; // 将这个顶点加入生成树
//生成树加入了新的顶点,从下标未1的顶点开始更新lowcost数组值
for (j = 0; j < g->vexnum; ++j){
if (lowcost[j] != 0 && g->Edge[k][j] < lowcost[j]){ // 如果新加入树的顶点k是的权值变小
adjvex[j] = g->Edge[k][j];
adjvex[j] = k; // 修改这条边邻接的顶点,也就是表示这条边是从选出的顶点k指过来的
}
}
}
}
int main(void){
MGraph *g = new MGraph;
CreateGraph(g);
MiniSpanTree_Prim(g);
system("pause");
return 0;
}