# 1584-min-cost-to-connect-all-points Try it on leetcode ## 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|, 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:

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

 

Constraints:

## Solution(Python) ```Python class UnionFind: def __init__(self, size): self.group = [0] * size self.rank = [0] * size for i in range(size): self.group[i] = i def find(self, a): if a != self.group[a]: self.group[a] = self.find(self.group[a]) return self.group[a] def union(self, a, b): groupA = self.find(a) groupB = self.find(b) if groupA == groupB: return False if self.rank[groupA] > self.group[groupB]: self.group[groupB] = groupA elif self.rank[groupB] > self.group[groupA]: self.group[groupA] = groupB else: self.group[groupB] = groupA self.rank[groupA] += 1 return True def isconnected(self, a, b): return self.find(a) == self.find(b) class Solution: def minCostConnectPoints(self, points: List[List[int]]) -> int: return self.optimized_prims(points) # Time Complexity: O(n2 log(n)) # space complexity: o(n^2) def kruskar(self, points: List[List[int]]) -> int: n = len(points) all_edges = [] for cur_node in range(n): for next_node in range(cur_node + 1, n): weight = abs(points[cur_node][0] - points[next_node][0]) + abs( points[cur_node][1] - points[next_node][1] ) all_edges.append((weight, cur_node, next_node)) all_edges.sort() uf = UnionFind(n) mst_cost = 0 edges_used = 0 for w, p1, p2 in all_edges: if uf.union(p1, p2): mst_cost += w edges_used += 1 if edges_used == n - 1: break return mst_cost # Time Complexity: O(n2 log(n)) # space complexity: o(n^2) def naiveprims(self, points: List[List[int]]) -> int: n = len(points) heap = [(0, 0)] in_mst = [False] * n mst_cost = 0 edges_used = 0 while edges_used < n: weight, cur_node = heapq.heappop(heap) if in_mst[cur_node]: continue in_mst[cur_node] = True mst_cost += weight edges_used += 1 for next_node in range(n): if not in_mst[next_node]: next_weight = self.manhattan_dist( points[cur_node], points[next_node] ) heapq.heappush(heap, (next_weight, next_node)) return mst_cost def manhattan_dist(self, point1, point2): return abs(point1[0] - point2[0]) + abs(point1[1] - point2[1]) # Time Complexity: O(n^2) # space complexity: o(n) def optimized_prims(self, points: List[List[int]]) -> int: n = len(points) mst_cost = 0 edges_used = 0 in_mst = [False] * n min_dist = [math.inf] * n min_dist[0] = 0 while edges_used < n: cur_min_edge = math.inf cur_node = -1 for node in range(n): if not in_mst[node] and cur_min_edge > min_dist[node]: cur_min_edge = min_dist[node] cur_node = node mst_cost += cur_min_edge edges_used += 1 in_mst[cur_node] = True for next_node in range(n): weight = self.manhattan_dist( points[cur_node], points[next_node]) if not in_mst[next_node] and min_dist[next_node] > weight: min_dist[next_node] = weight return mst_cost ```