Kruskal O(e * log e)
#define maxm // 最大边数
#define maxn // 最大顶点数
int u[maxm]; // 边的起点
int v[maxm]; // 终点
int w[maxm]; // 边权
int p[maxn]; // 并查
int r[maxm]; // 排序辅助数组
int n, m;
int cmp(int i, int j) {
return w[i] < w[j];
}
int findp(int x) {
return p[x] == x ? x : p[x] = findp(p[x]);
}
int kruskal() {
int ans = 0;
int cnt = 0;
for (int i = 0; i < m; i++) {
r[i] = i;
}
for (int i = 0; i < n; i++) {
p[i] = i;
}
sort(r, r + m, cmp);
for (int i = 0; i < m; i++) {
int e = r[i], x = findp(u[e]), y = findp(v[e]);
if (x != y) {
p[x] = y;
ans += w[e];
cnt++;
}
if (cnt >= n - 1) {
break;
}
}
return ans;
}
Prim O(v * v)
#define maxn
#define inf
int lc[maxn]; // 点到已选点集合中的点的最短路径长度
int d[maxn][maxn]; // 原图
int v[maxn]; // 已选标记
int n; // 总点数
int prim() {
int ans = 0;
memset(v, 0, sizeof v); // 清零
lc[0] = 0; // 选0号为起始节点
v[0] = 1;
for (int i = 1; i < n; i++) {
lc[i] = d[0][i];
}
for (int i = 1; i < n; i++) {
int m = inf, tmp;
for (int j = 0; j < n; j++) {
if (!v[j] && m > lc[j]) {
m = lc[tmp = j];
}
}
ans += m;
lc[tmp] = 0;
v[tmp] = 1;
for (int j = 0; j < n; j++) {
lc[j] = min(lc[j], d[tmp][j]);
}
}
return ans;
}