LeetCode 1135 最低成本联通所有城市

这篇博客介绍了如何利用kruskal和prim两种算法来解决LeetCode上的1135题,即找到连接所有城市的最低成本。kruskal方法依赖于边的权值排序和并查集,而prim方法则采用优先队列来动态排序权值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 kruskal方法(前置权值排序+并查集)

class UnionFind{
    private:
        int root_num;//联通分量个数
        vector<int> father;//存储树
        vector<int> subnode;//记录包含当前节点及子节点的个数,用于树的平衡
    public:
        UnionFind(int n){
            root_num=n;
            father.resize(n+1);
            subnode.resize(n+1);
            for(int i=1;i<n+1;i++){
                father[i]=i;
                subnode[i]=1;
            }
        }
        int find(int node){
            while(father[node]!=node){
                father[node]=father[father[node]];//路径压缩
                node=father[node];
            }
            // while(father[node]!=root){
            //     int pre_father=father[node];
            //     father[node]=root;
            //     node=pre_father;
            // }
            return node;
        }
        void connect(int x,int y){
            int root_x=find(x);
            int root_y=find(y);
            if(root_x!=root_y){
                // father[root_y]=root_x;
                //树的平衡
                if(subnode[root_x]>=subnode[root_y]){
                    father[root_y]=root_x;
                    subnode[root_x]+=subnode[root_y];
                }else{
                    father[root_x]=root_y;
                    subnode[root_y]+=subnode[root_x];
                }
                root_num--;
            }
        }
        bool ifConnect(int x,int y){
            return find(x)==find(y);
        }
        int get_root_num(){
            return root_num;
        }
};
class Solution {
public:
    int minimumCost(int n, vector<vector<int>>& connections) {
        sort(connections.begin(),connections.end(),[](vector<int>& a,vector<int>& b)->bool{return a[2]<b[2];});
        UnionFind uf(n);
        int mincost=0;
        for(vector<int>& edge:connections){ 
            if(uf.ifConnect(edge[0],edge[1]))   continue;
            uf.connect(edge[0],edge[1]);
            mincost+=edge[2];
        }
        return uf.get_root_num()==1?mincost:-1;
    }
};

 prim方法(优先队列-动态权值排序)

    int minimumCost(int n, vector<vector<int>>& connections) {
        //邻接矩阵的形式节点多的时候会超时限
        // vector<vector<int>> matrix(n+1,vector<int>(n+1,0));
        // for(auto& edge:connections){
        //     matrix[edge[0]][edge[1]]=edge[2];
        //     matrix[edge[1]][edge[0]]=edge[2];
        // }

        //用邻接表
        vector<vector<pair<int,int>>> matrix(n+1);
        for(auto& edge:connections){
            matrix[edge[0]].push_back({edge[1],edge[2]});
            matrix[edge[1]].push_back({edge[0],edge[2]});
        }

        priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> pq;
        // priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;//这个默认根据pair的first排序
        unordered_set<int> mst;
        pq.push({1,0});
        int mincost=0;
        while(!pq.empty() && mst.size()<n){
            pair<int,int> minNode=pq.top();
            pq.pop();
            if(mst.find(minNode.first)==mst.end()){
                mst.insert(minNode.first);
                mincost+=minNode.second;
                for(auto& edge:matrix[minNode.first]){
                    if(mst.find(edge.first)==mst.end())
                        pq.push(edge);
                }
            }
        }
        return mst.size()==n?mincost:-1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值