|
| 1 | +# 1135. Connecting Cities With Minimum Cost |
| 2 | + |
| 3 | +## Prim's Algorithm Solution |
| 4 | +- Run-time: O((V + E) log(V)) |
| 5 | +- Space: O(E) |
| 6 | +- E - Number of Edges |
| 7 | + |
| 8 | +This is question requires a minimum span tree(MST) algothrim. |
| 9 | +I choose to use Prim's algothrim because it is similar to Dijkstra's algorithm over Kruskal's algorithm. |
| 10 | +Knowing one will help you in learning the other. |
| 11 | + |
| 12 | +The idea with Prim's is to utilize a heap of vertices and an adjacent list. |
| 13 | +The resulting MST cannot produce a cycle due to the method of selecting an edge of an unvisited vertex. |
| 14 | +To select an edge, we use the heap sorted by the cost or weight of the edge. |
| 15 | +Each time we pop from the heap, we mark that vetrex as visited and add it's neighboring vertices' edges to the heap. |
| 16 | + |
| 17 | +The pseudocode could be represented as such: |
| 18 | +1. Select an arbitrary vertex to start with and add its neighboring vertices to the heap. |
| 19 | +2. Mark that arbitrary vertex as visited. |
| 20 | +3. While there are unvisited vertices: |
| 21 | + - Select the edge with the min weight of an unvisited vertex from top of heap. |
| 22 | + - Add the selected vertex to the visited vertices. |
| 23 | + - Add selected vertex's neighboring edges of unvisited vertices into the heap. |
| 24 | + |
| 25 | +Since we are sorting based on vertices, the sorting will take log(V) run-time. |
| 26 | +However, we have to sort this based on number of vertices or edges because we can be given a graph of islands or nodes that have edges to all nodes. |
| 27 | +That is why its O((V+E) log(V)) run-time. |
| 28 | + |
| 29 | +``` |
| 30 | +from collections import defaultdict |
| 31 | +
|
| 32 | +class Solution: |
| 33 | + def minimumCost(self, N: int, connections: List[List[int]]) -> int: |
| 34 | + |
| 35 | + def create_adj_list(connections): |
| 36 | + adj_list = defaultdict(list) |
| 37 | + for city1, city2, cost in connections: |
| 38 | + adj_list[city1].append(Vertex(city2, cost)) |
| 39 | + adj_list[city2].append(Vertex(city1, cost)) |
| 40 | + return adj_list |
| 41 | + |
| 42 | + adj_list = create_adj_list(connections) |
| 43 | + visited = set([N]) |
| 44 | + min_heap = list(adj_list[N] if N in adj_list else []) |
| 45 | + heapq.heapify(min_heap) |
| 46 | + min_cost = 0 |
| 47 | + while min_heap and len(visited) != N: |
| 48 | + vertex = heapq.heappop(min_heap) |
| 49 | + if vertex.to in visited: |
| 50 | + continue |
| 51 | + visited.add(vertex.to) |
| 52 | + min_cost += vertex.cost |
| 53 | + for vertex in adj_list[vertex.to]: |
| 54 | + heapq.heappush(min_heap, vertex) |
| 55 | + return min_cost if len(visited) == N else -1 |
| 56 | + |
| 57 | +class Vertex(object): |
| 58 | + |
| 59 | + def __init__(self, to, cost): |
| 60 | + self.to = to |
| 61 | + self.cost = cost |
| 62 | + |
| 63 | + def __lt__(self, other): |
| 64 | + return self.cost < other.cost |
| 65 | + |
| 66 | + def __repr__(self): |
| 67 | + return 'To: {}, Cost: {}'.format(self.to, self.cost) |
| 68 | +``` |
0 commit comments