Min Cost to Connect All Points

You are given an array points representing integer coordinates of some points on a 2D-plane, where points[i] = [xi, yi].

The cost of connecting two points [xi, yi] and [xj, yj] is the manhattan distance between them: |xi - xj| + |yi - yj|, where |val| denotes the absolute value of val.

Return the minimum cost to make all points connected. All points are connected if there is exactly one simple path between any two points.

Example 1:

Min Cost to Connect All Points_第1张图片

Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
Output: 20
Explanation:

We can connect the points as shown above to get the minimum cost of 20.
Notice that there is a unique path between every pair of points.

Example 2:

Input: points = [[3,12],[-2,5],[-4,1]]
Output: 18

思路:这题跟 1135 Connecting Cities With Minimum Cost 一模一样,就是抽象化的minimum spanning tree, 每次用最小的边去connect graph;Union Find 直觉解决问题;

class Solution {
    private class Connection {
        public int from;
        public int to;
        public int cost;
        public Connection(int from, int to, int cost) {
            this.from = from;
            this.to = to;
            this.cost = cost;
        }
    }
    
    private class UnionFind {
        private int[] father;
        private int size;
        public UnionFind(int n) {
            this.father = new int[n + 1];
            for(int i = 0; i <= n; i++) {
                father[i] = i;
            }
            this.size = n;
        }
        
        public int find(int x) {
            int j = x;
            while(father[j] != j) {
                j = father[j];
            }
            // path compression;
            while(x != j) {
                int fx = father[x];
                father[x] = j;
                x = fx;
            }
            return j;
        }
        
        public void union(int a, int b) {
            int root_a = find(a);
            int root_b = find(b);
            if(root_a != root_b) {
                father[root_a] = root_b;
                size--;
            }
        }
        
        public int getSize() {
            return this.size;
        }
    }
    
    public int minCostConnectPoints(int[][] points) {
        List clist = new ArrayList();
        int n = points.length;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                clist.add(new Connection(i, j, 
                                         getCost(points[i][0], points[i][1], points[j][0], points[j][1])));
            }
        }
        Collections.sort(clist, (a, b) -> (a.cost - b.cost));
        UnionFind uf = new UnionFind(n);
        int totalcost = 0;
        for(Connection connection: clist) {
            int a = connection.from;
            int b = connection.to;
            int cost = connection.cost;
            if(uf.find(a) != uf.find(b)) {
                uf.union(a, b);
                totalcost += cost;
            }
        }
        return totalcost;
    }
    
    private int getCost(int x1, int y1, int x2, int y2) {
        return Math.abs(x1 - x2) + Math.abs(y1 - y2);
    }
}

 思路2: 这题也可以用dijkstra来做,一个node,可以connect到别的node,可以有N条边,那么就是HashMap> Node里面存 id, cost,然后把所有的neighbor全部丢到priorityqueue里面按照cost sort,然后每次出来都是neighbor cost最小的,visited来收集node的id,这样把每条边都跑完,也就收集到了所有的node id,形成的cost就是最小的visit path cost;

class Solution {
    private class Node {
        public int index;
        public int cost;
        public Node(int index, int cost) {
            this.index = index;
            this.cost = cost;
        }
    }
    
    public int minCostConnectPoints(int[][] points) {
        HashMap> graph = new HashMap<>();
        int n = points.length;
        for(int i = 0; i < n; i++) {
            for(int j = i + 1; j < n; j++) {
                int from = i;
                int to = j;
                int cost = getCost(points[i][0], points[i][1], points[j][0], points[j][1]);
                graph.putIfAbsent(from, new ArrayList());
                graph.putIfAbsent(to, new ArrayList());
                graph.get(from).add(new Node(to, cost));
                graph.get(to).add(new Node(from, cost));
            }
        }
        
        PriorityQueue pq = new PriorityQueue((a, b) -> (a.cost - b.cost));
        pq.offer(new Node(0, 0));
        HashSet visited = new HashSet();
        
        int totalcost = 0;
        while(!pq.isEmpty()) {
            Node node = pq.poll();
            if(visited.contains(node.index)) {
                continue;
            }
            visited.add(node.index);
            totalcost += node.cost;
            
            if(graph.get(node.index) != null) {
                for(Node neighbor: graph.get(node.index)) {
                    if(!visited.contains(neighbor.index)) {
                        pq.offer(neighbor);
                    }
                }
            }
        }
        return totalcost;
    }
    
    private int getCost(int x1, int y1, int x2, int y2) {
        return Math.abs(x1 - x2) + Math.abs(y1 - y2);
    }
}

 

你可能感兴趣的:(Dijkstra,Union-Find)