leetcode 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 。
注意到任意两个点之间只有唯一一条路径互相到达。

代码

class Solution {
  int[] fa;
    public void  init()
    {
        for(int i=0;i<fa.length;i++)
            fa[i]=i;

    }
    public int  find(int x)
    {
        if(x!=fa[x])
          fa[x]=find(fa[x]);
        return fa[x];
    }
    public void   union(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y) return;
        fa[x]=y;

    }   
    class  edge{

        int x,x1,len;

        public edge(int x, int x1, int len) {
            this.x = x;
            this.x1 = x1;
            this.len = len;
        }
    }
    public int minCostConnectPoints(int[][] points) {

        int n = points.length;
        PriorityQueue<edge> priorityQueue=new PriorityQueue<>((o1, o2) -> o1.len-o2.len);
        for (int i = 0; i < n; i++) {//计算所有边的长度

            for (int j = i + 1; j < n; j++)
            {
                priorityQueue.add(new edge(i,j,Math.abs(points[i][0]-points[j][0])+Math.abs(points[i][1]-points[j][1])));
            }

        }
        fa=new int[n];
        init();
        int res=0;
        while (!priorityQueue.isEmpty())//每次选出最短的边
        {
            edge cur=priorityQueue.poll();
            if(find(cur.x)==find(cur.x1))//检查是否产生环路
                continue;
            union(cur.x,cur.x1);
            res+=cur.len;
        }
        return res;

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值