Files
python/TangDou/AcWing_TiGao/T3/MinialSpanningTree/1146_Prim.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

49 lines
1.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 310;
int n;
int g[N][N];
int dis[N];
bool st[N];
int res; // 最小生成树里面边的长度之和
void prim() {
memset(dis, 0x3f, sizeof dis); // 初始化所有距离为INF
dis[0] = 0; // 超级源点是在生成树中的
for (int i = 0; i <= n; i++) { // 注意:这里因为引入了超级源点,所以点的个数是n+1
int t = -1;
for (int j = 0; j <= n; j++)
if (!st[j] && (t == -1 || dis[t] > dis[j])) t = j;
if (i) res += dis[t];
// 有超级源点的题,是必然存在最小生成树的
// 注意这里也是需要从0~n共n+1个
for (int j = 0; j <= n; j++)
if (!st[j] && dis[j] > g[t][j])
dis[j] = g[t][j];
st[t] = true;
}
}
int main() {
cin >> n;
// 建立超级源点(0 <-> 1~n ),点权转化为超级源点到此节点的边权
for (int i = 1; i <= n; i++) {
int c;
cin >> c;
g[i][0] = g[0][i] = c;
}
// 本题是按矩阵读入的,不是按a,b,c方式读入的
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> g[i][j];
// 利用prim计算最小生成树
prim();
cout << res << endl;
return 0;
}