zoukankan      html  css  js  c++  java
  • 连接所有点的最小费用

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

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

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

    刚开始写出来的超出时间限制了:

    class Solution {
        public int minCostConnectPoints(int[][] points) {
            if(points.length==1){
                return 0;
            }
            int [][]cost=new int[points.length][points.length];
            for(int i=0;i<points.length;i++){
                for(int j=i;j<points.length;j++){
                    if(i==j){
                        cost[i][j]=Integer.MAX_VALUE;
                    }else{
                        cost[i][j]=Math.abs(points[i][0]-points[j][0])+Math.abs(points[i][1]-points[j][1]);
                        cost[j][i]=cost[i][j];
                    }
                }
            }
            List<Integer> in=new ArrayList();
            List<Integer> out=new ArrayList();
            for(int i=0;i<points.length;i++){
                out.add(i);
            }
            
            in.add(0);
            out.remove(0);
            int i=1;
            int sum=0;
            while(in.size()<points.length){
                sum=sum+helper(in,out,cost);
    
            }
            return sum;
    
        }
        public int helper(List<Integer> in,List<Integer> out,int [][]cost){
            int min=Integer.MAX_VALUE;
            int minFlag=-1;
            for(Integer i:in){
                for(Integer j:out){
                    if(cost[i][j]<min){
                        min=cost[i][j];
                        minFlag=j;
                    }
                }
            }
            in.add(minFlag);
            out.remove(out.indexOf(minFlag));
            return min;
    
        }
    }

    看到一个优化,每次添加节点之后,更新一个ds[]是从未加入节点到树的最小值,比如i,j都在里面,k在外面,j是新加入的

    那么ds[k]=min{ds[k],cost[j][k]},而且加入的要用Set存储,用list也会超出时间限制

    class Solution {
        public int minCostConnectPoints(int[][] points) {
            if(points.length==1){
                return 0;
            }
            int [][]cost=new int[points.length][points.length];
            for(int i=0;i<points.length;i++){
                for(int j=i+1;j<points.length;j++){
                    if(i==j){
                        cost[i][j]=Integer.MAX_VALUE;
                    }else{
                        cost[i][j]=Math.abs(points[i][0]-points[j][0])+Math.abs(points[i][1]-points[j][1]);
                        cost[j][i]=cost[i][j];
                    }
                }
            }
            Set<Integer> in=new HashSet();
            int []ds=new int[points.length];
            for(int i=0;i<points.length;i++){   
                ds[i]=cost[0][i];
            }
            in.add(0);
            
            int sum=0;
            for(int i=1;i<points.length;i++){
                int min=Integer.MAX_VALUE;
                int minF=-1;
                for(int j=0;j<points.length;j++){
                    if(!in.contains(j)&&ds[j]<min){
                        min=ds[j];
                        minF=j;
                    }
                }
                in.add(minF);
                sum=sum+min;
                for(int j=0;j<points.length;j++){
                    if(cost[minF][j]<ds[j]){
                        ds[j]=cost[minF][j];
                    }
                }
            }
            return sum;
        }
            
    }
  • 相关阅读:
    神代码
    初读《代码大全》
    单词频度统计
    AFO
    bzoj4816: [Sdoi2017]数字表格
    bzoj4006: [JLOI2015]管道连接
    bzoj4774: 修路
    bzoj3209: 花神的数论题
    bzoj4521: [Cqoi2016]手机号码
    COGS2314. [HZOI 2015] Persistable Editor
  • 原文地址:https://www.cnblogs.com/jieyi/p/14297413.html
Copyright © 2011-2022 走看看