【墨鳌】【最小生成树-克鲁斯卡尔算法】【并查集-数据结构】

最小生成树

描述

  • 输入:给出一个图(带权无向边集)
  • 输出:给出一个最小生成树(带权无向边集)

测试数据

vector<Edge> edges={
      Edge("A","I",6),
      Edge("A","J",6),
      Edge("A","G",5),
      //3
      Edge("B","F",2),
      Edge("B","J",1),
      Edge("B","H",6),
      Edge("B","D",4),
      Edge("B","K",3),
      //5
      Edge("C","J",8),
      Edge("C","G",7),
      Edge("C","L",7),
      //3
      Edge("D","K",2),
      //1
      Edge("E","G",4),
      Edge("E","L",2),
      //2
      Edge("F","I",4),
      Edge("F","J",3),
      //2
      Edge("G","I",4),
      Edge("G","J",3),
      //2
      Edge("H","K",4),
      //1
      Edge("K","L",1)
      //3+5+3+1+2+2+2+1+1=20
};

调用方法

int main() {
    Solution sol = Solution();
    auto ans=sol.minimumSpanningTree(edges);
    for(auto e:ans){
        cout<<e.u<<" "<<e.v<<" "<<e.weight<<endl;
    }
    return 0;
}

模板代码

//
// 有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
// Created by Mo-Ao on 2022-4-28 15:32:47
//

#ifndef TESTDEMO_SOLUTION_H
#define TESTDEMO_SOLUTION_H

#include <bits/stdc++.h>

using namespace std;

struct Edge {
    string u, v;
    int weight;

    Edge(string u, string v, int w) : u(u), v(v), weight(w) {}

    bool operator<(const Edge &edge) const {
        return weight < edge.weight;
    }
};

class UF {// 并查集模板
public:
    vector<int> fa, sz;
    int cnt;// 当前连通分量数目
    bool isUnited(int x, int y) {
        x = find(x);
        y = find(y);
        return x == y;
    }

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

    UF(int n) {//构造函数+初始化
        sz = vector<int>(n, 1);
        fa = vector<int>(n);
        for (int i = 0; i < n; i++)fa[i] = i;
        cnt = 0;
    }

    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (sz[x] < sz[y])swap(x, y);
        sz[x] += sz[y];
        fa[y] = x;
        --cnt;//把秩小的unite到大的上
    }
};


class Solution {
public:

    unordered_map<string, int> mapping(vector<Edge> &edges) {
        unordered_set<string> nodes;
        for (auto &edge: edges) {
            auto &u = edge.u;
            auto &v = edge.v;
            nodes.insert(u);
            nodes.insert(v);
        }
        int n = nodes.size();
        unordered_map<string, int> ids;
        int id = 0;
        for (auto &node: nodes) {
            ids[node] = id++;
        }
        return ids;
    }

    vector<Edge> minimumSpanningTree(vector<Edge>&edges) {
        auto ids = mapping(edges);
        UF uf(ids.size());
        vector<Edge> set;
        sort(begin(edges), end(edges));
        for (Edge &edge: edges) {
            auto &u = edge.u;
            auto &v = edge.v;
            if (!uf.isUnited(ids[u], ids[v])) {
                set.push_back(edge);
                uf.unite(ids[u], ids[v]);
            }
        }
        return set;
    }

};

#endif //TESTDEMO_SOLUTION_H

posted @ 2022-04-28 15:42  墨鳌  阅读(43)  评论(0编辑  收藏  举报