Problem 3: Optimize Water Distribution in a Village
Question 1: 这道题是个MST的题目吗?
Question 2: 区别点在于这道题可以自己大惊小怪?
有的店不需要别人联通了
主要的难点:我们怎么把这道题转化成一个母题:直接构造最小生成树
大家的思考:水源何在
打井和水源的关系:能不能假想一个水源==》我可以把水源看成一个点
Step1: Dummy Node for wells[i]
Step2: Sort all edges then kruskal algorithm
Step3: 在这个修改过的图中做MST算法和普通的构建结果有什么区别吗?
Question:怎么处理这个dummyNode?
这样的话,我们的MST不是build基于加过0这个点的MST了吗?会不会我们include的n-1条边没法链接到所有的村庄呢?
回答,完全不用处理
我们这道题目的是为了连接到所有的村庄吗?我们的目的是给每个村通上谁,如果你构建这个n-1条边里有一些便是跟dummyNode链接,说明这些村庄打井更合算
Thinking: 哪些村庄需要自己打井,哪些是需要引水
public int minCostToDistributeWater(int n, int[] wells, int[][] pipes) {
List<int[]> allEdges = new ArrayList<>();
addAddEdges(n, wells, pipes, allEdges);
return kruskals(n, allEdges);
}
private int kruskals(int n, List<int[]> allEdges) {
// step 1: sort all the edges
Collections.sort(allEdges, (a,b) -> Integer.compare(a[2], b[2]));
int minCost = 0;
int processedEdges = 0;
// step 2: apply kruskals
UnionFind uf = new UnionFind(n + 1);
for (int[] edge: allEdges) {
//其实也可以改变unionfind里的union这个方法,本题已经apply
int u = edge[0];
int v = edge[1];
int weight = edge[2];
if (uf.union(u, v)) {
preocessedEdges++;
minCost += weight;
if (precessedEdges == n) { // 保证n个村有水
break;
}
}
}
return minCost;
}
private void addAddEdges(int n, int[] wells, int[][] pipes, List<int[]> allEdges) {
// 所有从水源出去的边全部搞定
for (int i = 0; i < n; i++) {
allEdges.add(new int[]{0, i + 1, wells[i]});
}
for(int[] pipe: pipes) {
addEdges.add(pipe);
}
}
Tips: Union 的return type是可以用的!: 能不能union代表了你想union的这两个人是不是同一个帮拍的可以做的事把return type赋予一个物理意义:会不会构成环
void union(int a, int b)==> boolean union(int a, int b):我应不应该去union这两个点
Last updated