There are n houses in a village. We want to supply water for all the houses by building wells and laying pipes.
For each house i, we can either build a well inside it directly with cost
wells[i - 1] (note the -1 due to 0-indexing), or pipe in water from another well to it. The costs to lay pipes between houses are given by the array pipes where each pipes[j] = [house1j, house2j, costj] represents the cost to connect house1j and house2j together using a pipe. Connections are bidirectional, and there could be multiple valid connections between the same two houses with different costs.
Return the minimum total cost to supply water to all houses.

Input: n =3, wells =[1,2,2], pipes =[[1,2,1],[2,3,1]]Output: 3Explanation: The image shows the costs of connecting houses using pipes.The best strategy is to build a well in the first house with cost 1 and connect the other houses to it with cost 2 so the total cost is3.
Example 2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Input: n =2, wells =[1,1], pipes =[[1,2,1],[1,2,2]]Output: 2Explanation: We can supply water with cost two using one of the three options:Option 1:- Build a well inside house 1with cost 1.- Build a well inside house 2with cost 1.The total cost will be 2.Option 2:- Build a well inside house 1with cost 1.- Connect house 2with house 1with cost 1.The total cost will be 2.Option 3:- Build a well inside house 2with cost 1.- Connect house 1with house 2with cost 1.The total cost will be 2.Note that we can connect houses 1 and 2with cost 1 or with cost 2 but we will always choose **the cheapest option**.
We can model the problem as a graph where each house is a node. Building a well at house i is like connecting it to a virtual node 0 with cost wells[i-1]. All pipes are edges between houses. The minimum cost to supply water to all houses is the cost of the minimum spanning tree (MST) of this graph.
classSolution {
public:int minCostToSupplyWater(int n, vector<int>& wells, vector<vector<int>>& pipes) {
vector<vector<int>> edges;
for (int i =0; i < n; ++i) edges.push_back({0, i+1, wells[i]});
for (auto& p : pipes) edges.push_back(p);
sort(edges.begin(), edges.end(), [](auto& a, auto& b) { return a[2] < b[2]; });
vector<int> par(n+1);
iota(par.begin(), par.end(), 0);
function<int(int)> find = [&](int x) { return par[x] == x ? x : par[x] = find(par[x]); };
int ans =0, cnt =0;
for (auto& e : edges) {
int u = find(e[0]), v = find(e[1]);
if (u != v) {
par[u] = v;
ans += e[2];
if (++cnt == n) break;
}
}
return ans;
}
};
classSolution {
publicintminCostToSupplyWater(int n, int[] wells, int[][] pipes) {
List<int[]> edges =new ArrayList<>();
for (int i = 0; i < n; i++) edges.add(newint[]{0, i+1, wells[i]});
for (int[] p : pipes) edges.add(p);
edges.sort(Comparator.comparingInt(a -> a[2]));
int[] par =newint[n+1];
for (int i = 0; i <= n; i++) par[i]= i;
int ans = 0, cnt = 0;
for (int[] e : edges) {
int u = find(par, e[0]), v = find(par, e[1]);
if (u != v) {
par[u]= v;
ans += e[2];
if (++cnt == n) break;
}
}
return ans;
}
privateintfind(int[] par, int x) {
if (par[x]!= x) par[x]= find(par, par[x]);
return par[x];
}
}
classSolution {
funminCostToSupplyWater(n: Int, wells: IntArray, pipes: Array<IntArray>): Int {
val edges = mutableListOf<IntArray>()
for (i in wells.indices) edges.add(intArrayOf(0, i+1, wells[i]))
edges.addAll(pipes)
edges.sortBy { it[2] }
val par = IntArray(n+1) { it }
funfind(x: Int): Int = if (par[x] == x) x else { par[x] = find(par[x]); par[x] }
var ans = 0; var cnt = 0for (e in edges) {
val u = find(e[0]); val v = find(e[1])
if (u != v) {
par[u] = v
ans += e[2]
cnt++if (cnt == n) break }
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
defminCostToSupplyWater(self, n: int, wells: list[int], pipes: list[list[int]]) -> int:
edges = [[0, i+1, w] for i, w in enumerate(wells)] + pipes
edges.sort(key=lambda x: x[2])
par = list(range(n+1))
deffind(x: int) -> int:
if par[x] != x:
par[x] = find(par[x])
return par[x]
ans = cnt =0for u, v, c in edges:
fu, fv = find(u), find(v)
if fu != fv:
par[fu] = fv
ans += c
cnt +=1if cnt == n:
breakreturn ans