20230726-复习-最小生成树

45 阅读1分钟

最小生成树两种算法Kruskal、Prime。前者针对的是边,对边权升序排序然后从小到大遍历,结合并查集,直至所有点都连在一起。后者针对的是点,背模板。

leetcode-1584 连接所有点的最小费用

最小生成树模板题。

// Kruskal
class Solution {
public:
    int fa[1000];
    void init(int n){
        for(int i = 0; i < n; ++i){
            fa[i] = i;
        }
    }

    int find(int x){
        return fa[x] == x ? x : (fa[x] = find(fa[x]));
    }

    void merge(int x, int y){
        fa[find(x)] = find(y);
    }

    int getDistance(const vector<int>& a, const vector<int>& b){
        return abs(a[0] - b[0]) + abs(a[1] - b[1]);
    }
    int minCostConnectPoints(vector<vector<int>>& points) {
        int n = points.size();
        if(n == 1) return 0;
        init(n);
        vector<vector<int>> edges(n * (n - 1) / 2, vector<int>(3));
        int idx = 0;
        for(int i = 0; i < n; ++i){
            for(int j = i + 1; j < n; ++j){
                edges[idx][0] = i, edges[idx][1] = j, edges[idx][2] = getDistance(points[i], points[j]);
                ++idx;
            }
        }
        auto cmp = [](const vector<int>& a, const vector<int>& b){
            return a[2] < b[2];
        };
        sort(edges.begin(), edges.end(), cmp);
        int ans = 0, cnt = 0;
        for(int i = 0; i < n * (n - 1) / 2; ++i){
            int p1 = edges[i][0], p2 = edges[i][1];
            if(find(p1) != find(p2)){
                merge(p1, p2);
                ans += edges[i][2];
                ++cnt;
                if(cnt == n - 1) break;
            }
        }
        return ans;
    }
};
// Prime
class Solution {
public:
    int getDistance(const vector<int>& a, const vector<int>& b){
        return abs(a[0] - b[0]) + abs(a[1] - b[1]);
    }
    int minCostConnectPoints(vector<vector<int>>& points) {
        int n = points.size();
        if(n == 1) return 0;
        vector<vector<int>> graph(n, vector<int>(n));
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < n; ++j){
                graph[i][j] = getDistance(points[i], points[j]);
                graph[j][i] = getDistance(points[i], points[j]);
            }
        }
        vector<int> dis(n, INT_MAX);
        vector<int> vst(n);
        int ans = 0;
        for(int i = 0; i < n; ++i){
            int t = -1;
            for(int j = 0; j < n; ++j){
                if(vst[j] == 0 && (t == -1 || dis[t] > dis[j])) t = j;
            }
            if(i != 0) ans += dis[t];
            vst[t] = 1;
            for(int j = 0; j < n; ++j) dis[j] = min(dis[j], graph[t][j]);
        }
        return ans;
    }
};