算法实践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
*/
posted @ 2021-03-15 09:01  stff577  阅读(57)  评论(0)    收藏  举报