题目描述:
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]
, 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[i] = [house1, house2, cost]
represents the cost to connect house1
and house2
together using a pipe. Connections are bidirectional.
Find the minimum total cost to supply water to all houses.
Example 1:
Input: n = 3, wells = [1,2,2], pipes = [[1,2,1],[2,3,1]]
Output: 3
Explanation:
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 is 3.
Constraints:
1 <= n <= 10000
wells.length == n
0 <= wells[i] <= 10^5
1 <= pipes.length <= 10000
1 <= pipes[i][0], pipes[i][1] <= n
0 <= pipes[i][2] <= 10^5
pipes[i][0] != pipes[i][1]
class Solution {
public:
static bool comp(const vector<int>& a, const vector<int>& b)
{
return a[2]<b[2];
}
// 利用一个虚拟节点(n+1),只要这个虚拟节点和其他所有点连通即可,从而转化为最小生成树问题
int minCostToSupplyWater(int n, vector<int>& wells, vector<vector<int>>& pipes) {
for(int i=0;i<wells.size();i++) pipes.push_back({i+1,n+1,wells[i]});
sort(pipes.begin(),pipes.end(),comp); // Kruscal算法将边集排序再用贪心加入边
for(int i=1;i<=n+1;i++) parent[i]=i;
int cost=0;
for(vector<int> pipe:pipes)
{
int x=find(pipe[0]);
int y=find(pipe[1]);
if(x!=y)
{
cost+=pipe[2];
parent[x]=y;
}
}
return cost;
}
int find(int x)
{
if(x==parent[x]) return x;
else return find(parent[x]);
}
private:
unordered_map<int,int> parent;
};