题解 | #Prim/Kruskal#

最小生成树

http://www.nowcoder.com/practice/735a34ff4672498b95660f43b7fcd628

Prim

采用邻接矩阵,方便判重;

class Solution {
public:
    const int inf = 0x3f3f3f3f;
    struct Node{
        int v;
        int c;
        Node(int _v, int _c):v(_v), c(_c){}
        bool operator < (const Node& other) const{
            return c > other.c;
        }
    };
    int Adj[5010][5010];
    int vis[5010];
    int dist[5010];
    int miniSpanningTree(int n, int m, vector<vector<int> >& cost) {
        // write code here
        memset(Adj, inf, sizeof(Adj));
        memset(vis, false, sizeof(vis));
        memset(dist, inf, sizeof(dist));
        for(int i = 0 ; i < m; i ++){
            int u = cost[i][0] - 1;
            int v = cost[i][1] - 1;
            int c = cost[i][2];
            //去重边
            Adj[u][v] = min(Adj[u][v], c);
            Adj[v][u] = min(Adj[v][u], c);
        }
        priority_queue<Node> pq;
        pq.push({0, 0});
        dist[0] = 0;
        int ans = 0;
        int cnt = 0; //已经加入生成树集合的村庄数
        while(!pq.empty()){
            Node node = pq.top(); pq.pop();
            int u = node.v, cos = node.c;
            if(!vis[u]){
                ans += cos;
                vis[u] = true;
                cnt ++;
                if(cnt == n) break;
            }else continue;
            for(int v = 0; v < n; v ++){
                if(Adj[u][v] == inf) continue;
                int c = Adj[u][v];
                if(!vis[v] && c < dist[v]){
                    pq.push({v, c});
                    dist[v] = c;
                }
            }
        }
        return ans;
    }
};

Kruskal

class UnionSet{
private:
    vector<int> father;
public:
    UnionSet(int n){
        father.resize(n);
        for(int i = 0; i < n; i ++) father[i] = i;
    }
    int findFather(int x){
        if(father[x] != x) father[x] = findFather(father[x]);
        return father[x];
    }
    bool merge(int x, int y){
        int fa = findFather(x);
        int fb = findFather(y);
        if(fa != fb){
            father[fa] = fb;
            return true;
        }
        return false;
    }
};
class Solution {
public:
    struct Edge{
        int u, v;
        int cos;
        Edge(int _u, int _v, int _cos):u(_u), v(_v), cos(_cos){}
        bool operator < (const Edge& edge) const{
            return cos < edge.cos;
        }
    };
    int miniSpanningTree(int n, int m, vector<vector<int> >& cost) {
        // write code here
        UnionSet ust(n);
        unordered_map<int, unordered_map<int, int>> ump;
        for(int i = 0; i < m; i ++){
            int u = cost[i][0] - 1, v = cost[i][1] - 1, c = cost[i][2];
            if(u > v){
                swap(u, v);
            }
            if(ump.find(u) == ump.end() || ump[u].find(v) == ump[u].end()){
                ump[u][v] = c;
            }else{
                ump[u][v] = min(ump[u][v], c); //去重边
            }
        }
        vector<Edge> edges;
        for(auto it:ump){
            int u = it.first;
            auto mp = it.second;
            for(auto iit:mp){
                int v = iit.first, c = iit.second;
                edges.push_back({u, v, c});
            }
        }
        sort(edges.begin(), edges.end());
        m = edges.size();
        int ans = 0;
        for(int i = 0; i < m; i ++){
            int u = edges[i].u, v = edges[i].v, c = edges[i].cos;
            if(ust.merge(u, v)){
                ans += c;
            }
        }
        return ans;
    }
};
全部评论

相关推荐

无敌虾孝子:喜欢爸爸还是喜欢妈妈
点赞 评论 收藏
分享
10-09 22:05
666 C++
找到工作就狠狠玩CSGO:报联合国演讲,报电子烟设计与制造
点赞 评论 收藏
分享
2 收藏 评论
分享
牛客网
牛客企业服务