算法实践1-1 Prim
问题:
Prim构造最小生成树的过程。
解析
每次在最小生成树外的点中找到距离当前最小生成树距离最近的点,将其加入最小生成树内,同时更新跟它相邻的点距离最小生成树的距离。直到找不到点或者生成最小生成树为止。
解析图

设计
int prim() {
d[1] = 0;
ans = 0;
for (1 to n) {
for (v : n) {
找到距离最小生成树最近的点j
}
if (找不到) return -1;
vis[j] = 1;
ans += d[j];
for (v : n) {
if (v没被访问过) d[v] = min(d[v], dis[j][v]);
}
}
return ans;
}
分析
\(O(n^2)\)遍历点,总时间复杂度为\(O(n^2)\)
源码
https://github.com/Sstee1XD/Algorithm_homework/tree/main/实验1-1 Prim
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7;
const int inf = 0x3f3f3f3f;
int dis[N][N], d[N], vis[N];
int n, m, u, v, w;
int prim() {
int ans = 0;
d[1] = 0;
for (int i = 1; i <= n; ++i) {
int nxt = -1, mind = 0x3f3f3f;
for (int j = 1; j <= n; ++j) {
if (vis[j]) continue;
if (d[j] < mind) {
nxt = j;
mind = d[j];
}
}
if (nxt == -1) return -1;
vis[nxt] = 1;
ans += mind;
for (int j = 1; j <= n; ++j) {
if (!vis[j]) d[j] = min(d[j], dis[nxt][j]);
}
}
return ans;
}
int main() {
memset(dis, 0x3f, sizeof(dis));
memset(d, 0x3f, sizeof(d));
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; ++i) {
scanf("%d %d %d", &u, &v, &w);
dis[u][v] = w;
dis[v][u] = w;
}
printf("%d\n", prim());
return 0;
}
/*
4 5
1 2 4
1 3 6
1 4 3
2 3 1
2 4 2
*/

浙公网安备 33010602011771号