Posts Min Cost to Connect All Points
Post
Cancel

Min Cost to Connect All Points

Problem Description

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, wherevaldenotes 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.

leetcode

Solution

The minimum cost to connect all points is basically about finding the minimum spanning tree with weights defined byx1-x2+y1-y2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
class Solution {
    
    public int minCostConnectPoints(int[][] points) {

        //number of nodes/vertices
        int n = points.length;

        //number of edges = nC2 -> n*(n-1)/2 
        int e = n*(n-1)/2;

        //to store all edges with their weights
        int[][] edges = new int[e][3];
        
        //to add edge info at index idx in edges array
        int idx=0;
        
        //loop through all the points combinations
        //each combination can form an edge with weight = |x1-x2| + |y1-y2|
        for(int i=0; i<n; i++){

            //we start with j=i+1 to avoid duplicate (point A to point B is same as point B to point A)
            for(int j=i+1; j<n; j++){

                //calculate the weight of that edge
                int w = Math.abs(points[i][0]-points[j][0]) + Math.abs(points[i][1]-points[j][1]);

                //store edge info
                edges[idx][0] = i;
                edges[idx][1] = j;
                edges[idx][2] = w;
                
                //increment edge count
                idx++;

            }
            
        }

        //the minimum cost is the MST 
        return spanningTree(n, e, edges);

    }

    //Minimum Spanning Tree
    static int spanningTree(int V, int E, int edges[][]){
        
        Arrays.sort(edges, (o1, o2) -> o1[2] > o2[2]?1: (o1[2] < o2[2]?-1:0));
        
        //init parent array -> initially with no edges, every node will be its own parent
        int[] parent = new int[V];
        for(int i=0; i<parent.length; i++){
            parent[i] = i;
        }
        
        //init total cost
        int cost = 0;
        
        //check for each edge if it can be included
        for(int i=0; i<E; i++){
            
            //get the nodes forming the current edge
            int u = edges[i][0];
            int v = edges[i][1];
            
            //if both the nodes are part of the same connected component, we cannot choose it as they will form a cycle if included
            //if they have different leaders, they can be merged as a single component. pick that edge and add the cost
            if(union(u, v, parent)){
                cost += edges[i][2];
            }
            
        }
        
        return cost;
        
    }
    
    public static int find(int x, int[] parent){
        
        while(parent[x] != x){
            x = parent[x];
        }
        
        return parent[x];
        
    }
    
    public static boolean union(int x, int y, int[] parent){
        
        //if parent of x and y are same, union is not needed so return false
        if(find(x, parent) == find(y, parent)) return false;
        
        //else, merge them and return true
        //to merge them, we need to change the parent of the leader of one component as the leader of second component
        parent[find(x, parent)] = find(y, parent);
        
        return true;
        
    }


}
This post is licensed under CC BY 4.0 by the author.