噢莫加纳加加加 • 21小时前
#include <bits/stdc++.h> // 引入 C++ 常用标准库头文件
#define inf 0x3f3f3f3f // 定义一个很大的数,用来表示“无穷大”
using namespace std; // 使用标准命名空间,方便直接使用 cin、cout 等
int g[105][105]; // 邻接矩阵,存储图中每两个点之间的边权
int dis[105], n; // dis 数组记录每个点到当前最小生成树集合的最小边权,n 为节点数量
bool vis[105]; // 标记数组,vis[i] 为 true 表示节点 i 已被加入最小生成树
void prim(int v) { // Prim 算法函数,v 是起始节点
vis[v] = 1; // 将起始节点 v 标记为已访问,表示它进入最小生成树集合
dis[v] = 0; // 起始节点到最小生成树集合的距离设为 0
for (int i = 0; i < n; i++) { // 遍历所有节点
if (g[v][i] != 0) { // 如果起始节点 v 到节点 i 有边
dis[i] = g[v][i]; // 用这条边的权值初始化节点 i 到集合的最小边权
}
}
for (int i = 0; i < n; i++) { // 进行 n 轮扩展,每轮加入一个节点
int min = inf; // 初始化当前最小边权为无穷大
for (int j = 0; j < n; j++) { // 遍历所有节点,寻找未访问节点中 dis 最小的节点
if (!vis[j] && dis[j] < min) { // 如果节点 j 未访问,且它到集合的距离更小
min = dis[j]; // 更新当前最小距离
v = j; // 记录当前距离最小的节点编号
}
}
vis[v] = 1; // 将选出的节点 v 标记为已访问,加入最小生成树集合
for (int j = 0; j < n; j++) { // 遍历所有节点,更新未访问节点的最小边权
if (!vis[j] && g[v][j] != 0 && dis[j] > g[v][j]) { // 如果节点 j 未访问,且通过新加入的节点 v 能获得更小的边权
dis[j] = g[v][j]; // 更新节点 j 到最小生成树集合的最小边权
}
}
}
}
int main() { // 主函数
cin >> n; // 读入节点数量 n
int sum = 0; // 用于累加最小生成树的总权值
memset(dis, inf, sizeof(dis)); // 将 dis 数组初始化为很大的值
memset(vis, 0, sizeof(vis)); // 将 vis 数组初始化为 0,表示所有节点都未访问
for (int i = 0; i < n; i++) { // 读入邻接矩阵的每一行
for (int j = 0; j < n; j++) { // 读入邻接矩阵的每一列
cin >> g[i][j]; // 读入节点 i 到节点 j 的边权
}
}
int t = 1; // 选择节点 1 作为 Prim 算法的起点
prim(t); // 从节点 1 开始执行 Prim 算法
for (int i = 0; i < n; i++) { // 遍历所有节点
sum = sum + dis[i]; // 累加每个节点到最小生成树集合的最小边权
}
cout << sum; // 输出最小生成树的总权值
return 0; // 程序正常结束
}
评论:
请先登录,才能进行评论