Skip to content

Commit 5d24fbc

Browse files
committed
feat: add solutions to lc problem: No.1168
No.1168. Optimize Water Distribution in a Village
1 parent ead6d2a commit 5d24fbc

File tree

9 files changed

+330
-214
lines changed

9 files changed

+330
-214
lines changed

solution/1100-1199/1168.Optimize Water Distribution in a Village/README.md

+111-72
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@
6565

6666
<!-- 这里可写通用的实现逻辑 -->
6767

68-
最小生成树问题。
68+
**方法一:Kruskal 算法(最小生成树)**
6969

70-
**方法一:Kruskal 算法**
70+
我们假设有一个水井编号为 $0$,那么我们可以将每个房子与水井 $0$ 之间的连通性看作是一条边,每条边的权值为该房子建造水井的成本。同时,我们将每个房子之间的连通性也看作是一条边,每条边的权值为铺设管道的成本。这样一来,我们就可以将本题转化成求一张无向图的最小生成树的问题。
7171

72-
对于本题,可以将节点 0 视为水库,水库到房子间的成本等于房子内建造水井的成本。因此此题可以转换为最小生成树问题。
72+
我们可以使用 Kruskal 算法求出无向图的最小生成树。我们先把水井 $0$ 与房子之间的一条边加入 $pipes$ 数组中,然后将 $pipes$ 数组按照边权值从小到大排序。随后,我们遍历每一条边,如果这条边连接了不同的连通分量,我们就选用这条边,并将对应连通分量合并。如果当前的连通分量恰好为 $1$,那么我们就找到了最小生成树,此时的答案即为当前边权值,我们将其返回即可。
73+
74+
时间复杂度 $O((m + n) \times \log (m + n))$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别是 $pipes$ 数组和 $wells$ 数组的长度。
7375

7476
<!-- tabs:start -->
7577

@@ -82,27 +84,26 @@ class Solution:
8284
def minCostToSupplyWater(
8385
self, n: int, wells: List[int], pipes: List[List[int]]
8486
) -> int:
85-
for i, w in enumerate(wells):
86-
pipes.append([0, i + 1, w])
87-
pipes.sort(key=lambda x: x[2])
88-
89-
p = list(range(n + 1))
90-
91-
def find(x):
87+
def find(x: int) -> int:
9288
if p[x] != x:
9389
p[x] = find(p[x])
9490
return p[x]
9591

96-
res = 0
97-
for u, v, w in pipes:
98-
if find(u) == find(v):
92+
for i, w in enumerate(wells, 1):
93+
pipes.append([0, i, w])
94+
pipes.sort(key=lambda x: x[2])
95+
p = list(range(n + 1))
96+
ans = 0
97+
for i, j, c in pipes:
98+
pa, pb = find(i), find(j)
99+
if pa == pb:
99100
continue
100-
p[find(u)] = find(v)
101-
res += w
101+
p[pa] = pb
102+
ans += c
102103
n -= 1
103104
if n == 0:
104105
break
105-
return res
106+
return ans
106107
```
107108

108109
### **Java**
@@ -114,32 +115,32 @@ class Solution {
114115
private int[] p;
115116

116117
public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
117-
int[][] all = new int[pipes.length + n][3];
118-
int idx = 0;
119-
for (int[] pipe : pipes) {
120-
all[idx++] = pipe;
118+
var nums = new int[n + pipes.length][0];
119+
int j = 0;
120+
for (var pipe : pipes) {
121+
nums[j++] = pipe;
121122
}
122-
for (int j = 0; j < n; ++j) {
123-
all[idx++] = new int[] {0, j + 1, wells[j]};
123+
for (int i = 0; i < n; ++i) {
124+
nums[j++] = new int[]{0, i + 1, wells[i]};
124125
}
126+
Arrays.sort(nums, (a, b) -> a[2] - b[2]);
125127
p = new int[n + 1];
126-
for (int i = 0; i < p.length; ++i) {
128+
for (int i = 1; i <= n; ++i) {
127129
p[i] = i;
128130
}
129-
Arrays.sort(all, Comparator.comparingInt(a -> a[2]));
130-
int res = 0;
131-
for (int[] e : all) {
132-
if (find(e[0]) == find(e[1])) {
131+
int ans = 0;
132+
for (var x : nums) {
133+
int pa = find(x[0]), pb = find(x[1]);
134+
if (pa == pb) {
133135
continue;
134136
}
135-
p[find(e[0])] = find(e[1]);
136-
res += e[2];
137-
--n;
138-
if (n == 0) {
137+
ans += x[2];
138+
p[pa] = pb;
139+
if (--n == 0) {
139140
break;
140141
}
141142
}
142-
return res;
143+
return ans;
143144
}
144145

145146
private int find(int x) {
@@ -156,69 +157,107 @@ class Solution {
156157
```cpp
157158
class Solution {
158159
public:
159-
vector<int> p;
160-
161160
int minCostToSupplyWater(int n, vector<int>& wells, vector<vector<int>>& pipes) {
162-
p.resize(n + 1);
163-
for (int i = 0; i < p.size(); ++i) p[i] = i;
164-
for (int i = 0; i < n; ++i) pipes.push_back({0, i + 1, wells[i]});
165-
sort(pipes.begin(), pipes.end(), [](const auto& a, const auto& b) {
161+
for (int i = 0; i < n; ++i) {
162+
pipes.push_back({0, i + 1, wells[i]});
163+
}
164+
sort(pipes.begin(), pipes.end(), [](const vector<int>& a, const vector<int>& b) {
166165
return a[2] < b[2];
167166
});
168-
int res = 0;
169-
for (auto e : pipes) {
170-
if (find(e[0]) == find(e[1])) continue;
171-
p[find(e[0])] = find(e[1]);
172-
res += e[2];
173-
--n;
174-
if (n == 0) break;
167+
int p[n + 1];
168+
iota(p, p + n + 1, 0);
169+
function<int(int)> find = [&](int x) {
170+
if (p[x] != x) {
171+
p[x] = find(p[x]);
172+
}
173+
return p[x];
174+
};
175+
int ans = 0;
176+
for (const auto& x : pipes) {
177+
int pa = find(x[0]), pb = find(x[1]);
178+
if (pa == pb) {
179+
continue;
180+
}
181+
p[pa] = pb;
182+
ans += x[2];
183+
if (--n == 0) {
184+
break;
185+
}
175186
}
176-
return res;
177-
}
178-
179-
int find(int x) {
180-
if (p[x] != x) p[x] = find(p[x]);
181-
return p[x];
187+
return ans;
182188
}
183189
};
184190
```
185191
186192
### **Go**
187193
188194
```go
189-
var p []int
190-
191-
func minCostToSupplyWater(n int, wells []int, pipes [][]int) int {
192-
p = make([]int, n+1)
193-
for i := 0; i < len(p); i++ {
194-
p[i] = i
195-
}
195+
func minCostToSupplyWater(n int, wells []int, pipes [][]int) (ans int) {
196196
for i, w := range wells {
197197
pipes = append(pipes, []int{0, i + 1, w})
198198
}
199-
sort.Slice(pipes, func(i, j int) bool {
200-
return pipes[i][2] < pipes[j][2]
201-
})
202-
res := 0
203-
for _, e := range pipes {
204-
if find(e[0]) == find(e[1]) {
199+
sort.Slice(pipes, func(i, j int) bool { return pipes[i][2] < pipes[j][2] })
200+
p := make([]int, n+1)
201+
for i := range p {
202+
p[i] = i
203+
}
204+
var find func(int) int
205+
find = func(x int) int {
206+
if p[x] != x {
207+
p[x] = find(p[x])
208+
}
209+
return p[x]
210+
}
211+
212+
for _, x := range pipes {
213+
pa, pb := find(x[0]), find(x[1])
214+
if pa == pb {
205215
continue
206216
}
207-
p[find(e[0])] = find(e[1])
208-
res += e[2]
217+
p[pa] = pb
218+
ans += x[2]
209219
n--
210220
if n == 0 {
211221
break
212222
}
213223
}
214-
return res
224+
return
215225
}
226+
```
216227

217-
func find(x int) int {
218-
if p[x] != x {
219-
p[x] = find(p[x])
220-
}
221-
return p[x]
228+
### **TypeScript**
229+
230+
```ts
231+
function minCostToSupplyWater(
232+
n: number,
233+
wells: number[],
234+
pipes: number[][],
235+
): number {
236+
for (let i = 0; i < n; ++i) {
237+
pipes.push([0, i + 1, wells[i]]);
238+
}
239+
pipes.sort((a, b) => a[2] - b[2]);
240+
const p = new Array(n + 1).fill(0).map((_, i) => i);
241+
const find = (x: number): number => {
242+
if (p[x] !== x) {
243+
p[x] = find(p[x]);
244+
}
245+
return p[x];
246+
};
247+
let ans = 0;
248+
for (const [i, j, c] of pipes) {
249+
const pa = find(i);
250+
const pb = find(j);
251+
if (pa === pb) {
252+
continue;
253+
}
254+
p[pa] = pb;
255+
ans += c;
256+
if (--n === 0) {
257+
break;
258+
}
259+
}
260+
return ans;
222261
}
223262
```
224263

0 commit comments

Comments
 (0)