1584. 连接所有点的最小费用

给定二维平面上的点集合,每两点间连接的费用为它们之间的曼哈顿距离。任务是找到连接所有点的最小总费用,确保任意两点间有唯一路径。示例展示了不同情况下的最小费用计算。解决方案提到可以采用并查集配合Kruskal算法来求解问题。
摘要由CSDN通过智能技术生成

1584. 连接所有点的最小费用

给你一个points 数组,表示 2D 平面上的一些点,其中 points[i] = [xi, yi] 。

连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的绝对值。

请你返回将所有点连接的最小总费用。只有任意两点之间 有且仅有 一条简单路径时,才认为所有点都已连接。

 

示例 1:

输入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
输出:20
解释:

我们可以按照上图所示连接所有点得到最小总费用,总费用为 20 。
注意到任意两个点之间只有唯一一条路径互相到达。


示例 2:

输入:points = [[3,12],[-2,5],[-4,1]]
输出:18


示例 3:

输入:points = [[0,0],[1,1],[1,0],[-1,1]]
输出:4


示例 4:

输入:points = [[-1000000,-1000000],[1000000,1000000]]
输出:4000000


示例 5:

输入:points = [[0,0]]
输出:0
 

提示:

1 <= points.length <= 1000
-106 <= xi, yi <= 106
所有点 (xi, yi) 两两不同。


基本思路:并查集+Kruskal

class UF{
    private:
        vector<int> parent,psize;
    public:
        UF(int len){
            parent.resize(len,0);
            psize.resize(len,1);
            for(int i=0;i<len;i++){
                parent[i]=i;
            }
        }

        int find(int x){

            return x==parent[x]?x:parent[x]=find(parent[x]);
        }

        bool connect(int x,int y){
            int px=find(x);
            int py=find(y);
            if(px==py)
                return false;
            
            if(psize[px]<psize[py]){
                swap(px,py);
            }
            parent[py]=px;
            psize[px]+=psize[py];
            return true;
        }
};

struct Edge{
    int len,x,y;
    Edge(int _len,int _x,int _y):len(_len),x(_x),y(_y){};
};
class Solution {
public:

    int minCostConnectPoints(vector<vector<int>>& points) {
        auto calDist=[&](int x,int y)->int {
            return abs(points[x][0]-points[y][0])+abs(points[x][1]-points[y][1]);
        };

        int len=points.size();
        UF *uf=new UF(len);
        vector<Edge> edges;
        for(int i=0;i<len;i++){

            for(int j=i+1;j<len;j++){
                edges.emplace_back(calDist(i,j),i,j);
            }
        }
        sort(edges.begin(),edges.end(),[](Edge &a,Edge &b){
            return a.len<b.len;
        });

        int ans=0,cnt=1;
        for(auto &[d,x,y]:edges){
            if(uf->connect(x,y)){
                ans+=d;
                cnt++;
                if(cnt==len)
                    break;

            }
        }
        return ans;

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值