• 1584. 连接所有点的最小费用-图/最小生成树-中等


    问题描述

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

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

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

    输入: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) 两两不同。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/min-cost-to-connect-all-points

    解答

    /*prim算法,算法描述,请参考别人写的文章https://blog.csdn.net/qq_37241934/article/details/81133651
    本题就是用prim算法构建一颗最小生成树。
    
    */
    class Solution {
        int n;
        public int minCostConnectPoints(int[][] points) {
            n = points.length;
            int[][] costs = new int[n][n];//记录costs[i][j]表示i到j的距离(开销)。
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    costs[i][j] = Math.abs(points[i][0]-points[j][0])+Math.abs(points[i][1]-points[j][1]);
                }
            }
            return minimumSpanningTree(costs, 0);//以0为起点,建立最小生成树。
        }
        public int minimumSpanningTree(int[][] costs, int start){
            int res = 0;
            int treeNode = 1;//节点数量, 初始树节点数量为1
            int[] lowCosts = new int[n];//lowCosts[i]表示:节点i到生成树中的某个节点(比如最开始是到start)的最小权值(开销)。
            int[] mts = new int[n];//mts[i]表示:距离节点i最近的一个生成树中的节点。
            //下面要初始化这两个数组
            for(int i=0;i<n;i++){
                lowCosts[i] = costs[start][i];
                mts[i] = i==start?-1:start;//mts[i]=-1表示i节点已经是生成树中的一员了。
            }
            
            while(treeNode<n){
                int newNode = -1;
                int min = Integer.MAX_VALUE;
                //下面寻找新的节点,将lowCosts中的最小值选出来作为新节点。
                for(int i=0;i<n;i++){
                    if(mts[i]!=-1 && lowCosts[i]<min){
                        newNode = i;
                        min = lowCosts[i];
                    }
                }
                //newNode!=-1表示找到了新的可以加入树的节点,那么找到了之后就要用newNode作为start,所以要更新两个数组。
                if(newNode!=-1){
                    treeNode++;
                    mts[newNode]=-1;//把newNode加入生成树
                    res+=min;//更新距离
                    //下面更新数组。
                    for(int i=0;i<n;i++){
                        if(mts[i]!=-1 && costs[newNode][i]<lowCosts[i]){
                            lowCosts[i] = costs[newNode][i];
                            mts[i] = newNode;
                        }
                    }
                }
            }
            return res;
        }
    }
  • 相关阅读:
    总结在ssm整合中,Mybatis出现Mapped Statements collection already contains value for xxxxx的解决方案
    一般二叉树的创建,前序,中序,后序遍历
    无向图的广度优先遍历和深度优先遍历(简易实现)
    为什么局部内部类中访问同一方法中的变量,该变量一定要是final修饰的
    uml统一建模语言学习笔记(一)
    Font Awesome 字体使用方法, 兼容ie7+
    Java的三种代理模式&完整源码分析
    xxl-job源码分析
    MySQl看这一篇就够了
    第二部分:Spring中配置mongodb
  • 原文地址:https://www.cnblogs.com/xxxxxiaochuan/p/13738780.html
Copyright © 2020-2023  润新知