-
Notifications
You must be signed in to change notification settings - Fork 53
/
Copy path1135. Connecting Cities With Minimum Cost.js
126 lines (111 loc) · 3.41 KB
/
1135. Connecting Cities With Minimum Cost.js
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// There are N cities numbered from 1 to N.
// You are given connections, where each connections[i] = [city1, city2, cost] represents the cost to connect city1 and city2 together. (A connection is bidirectional: connecting city1 and city2 is the same as connecting city2 and city1.)
// Return the minimum cost so that for every pair of cities, there exists a path of connections (possibly of length 1) that connects those two cities together. The cost is the sum of the connection costs used. If the task is impossible, return -1.
//
// Example 1:
//
// [1]
// / \
// 6 5
// / \
// [3] - 1 - [2]
//
// Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]]
// Output: 6
// Explanation:
// Choosing any 2 edges will connect all cities so we choose the minimum 2.
//
// Example 2:
//
// [1] - 3 - [2]
// [3] - 4 - [4]
//
// Input: N = 4, connections = [[1,2,3],[3,4,4]]
// Output: -1
// Explanation:
// There is no way to connect all cities even if all edges are used.
//
// Note:
//
// 1 <= N <= 10000
// 1 <= connections.length <= 10000
// 1 <= connections[i][0], connections[i][1] <= N
// 0 <= connections[i][2] <= 10^5
// connections[i][0] != connections[i][1]
/**
* @param {number} N
* @param {number[][]} connections
* @return {number}
*/
// 1) Kruskal's algorithm + Union Find with Path Compression
// Introduction to Kruskal's algorithm https://www.youtube.com/watch?v=71UQH7Pr9kU
// Introduction to Union Find https://www.youtube.com/watch?v=0jNmHPfA_yE
// Introduction to Union Find Path Compression https://www.youtube.com/watch?v=VHRhJWacxis
//
// We use Kruskal’s algorithm to generate a minimum spanning tree for the graph. Use Union-Find to detect cycle.
//
// Idea is simple:
//
// 1. Sort edges to no-decreasing order
// 2. Pick the smallest edge that does not form a cycle
// 3. Repeat until minimum spanning tree (MST) is formed and every node is connected.
//
// Implemented Union-Find with path compression to improve efficiency.
const minimumCost1 = (N, connections) => {
let n = N;
const parents = {};
for (let i = 0; i < N; i++) parents[i] = i;
// Find root
const find = (u) => {
if (u === parents[u]) return u;
return parents[u] = find(parents[u]); // path compression
};
const union = (u, v) => {
const p1 = find(u);
const p2 = find(v);
if (p1 !== p2) {
parents[p1] = p2; // or parents[p2] = p1 which does not matter
n--;
}
};
connections.sort((a, b) => a[2] - b[2]);
let res = 0;
for (const [u, v, cost] of connections) {
if (find(u) !== find(v)) {
union(u, v);
res += cost;
}
}
return n === 1 ? res : -1;
};
// 2) Similar to 1), set parents value in find
// Similar
// 947. Most Stones Removed with Same Row or Column
// 1135. Connecting Cities With Minimum Cost
const minimumCost = (N, connections) => {
let n = N;
const parents = {};
// Find root
const find = (u) => {
if (parents[u] == null) parents[u] = u;
else if (parents[u] !== u) parents[u] = find(parents[u]); // path compression
return parents[u];
};
const union = (u, v) => {
const p1 = find(u);
const p2 = find(v);
if (p1 !== p2) {
parents[p1] = p2; // or parents[p2] = p1 which does not matter
n--;
}
};
connections.sort((a, b) => a[2] - b[2]);
let res = 0;
for (const [u, v, cost] of connections) {
if (find(u) !== find(v)) {
union(u, v);
res += cost;
}
}
return n === 1 ? res : -1;
};