LeetCode 1168. Optimize Water Distribution in a Village

Subject description:

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]

answer:

1, wells the cost of the array can be seen from the connections between the villages to 0 at index

2, village (numbered 1 ~ n) only the water village with a through passage to 0 of the villages - i.e. just need to communicate with all villages, i.e. forming a minimum spanning tree, Kruskal's algorithm may be used: i.e., :

The weight according to the order of the right side (small to large) is added with the spanning tree, but when added to the spanning tree to form a ring with the edges will not join the edges. Until the tree contains {\ displaystyle V-1} V-1up edges. These edges is composed of the minimum spanning tree of FIG.

The time complexity of the algorithm is the Kruskal {\ DisplayStyle E \ log E} {\displaystyle E\log E}.

3, it is determined whether the two villages disjoint-set can be connected. Lee215 implementation as follows:

int[] uf;
    public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
        uf = new int[n + 1];
        List<int[]> edges = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            uf[i + 1] = i + 1;
            edges.add(new int[] {0, i + 1, wells[i]});
        }
        for (int[] p : pipes) {
            edges.add(p);
        }
        Collections.sort(edges, (a, b) -> Integer.compare(a[2], b[2]));

        int res = 0;
        for (int[] e : edges) {
            int x = find(e[0]), y = find(e[1]);
            if (x != y) {
                res += e[2];
                uf[x] = y;
                --n;
            }
        }
        return res;
    }

    private int find(int x) {
        if (x != uf[x]) uf[x] = find(uf[x]);
        return uf[x];
    }

This implementation is very simple.

I applied to achieve their common class WQUPC set of templates (weighted quick union with path comparess), it looks a little redundant, but can enhance performance.

class Solution {
    class WQUPC {
        int[] id;
        int[] sz;
        WQUPC(int n) {
            id = new int[n];
            sz = new int[n];
            for(int i = 0; i < n; i++) {
                id[i] = i;
                sz[i] = 1;
            }
        }
        int root(int i) {
            while(id[i] != i) {
                id[i] = id[id[i]];
                i = id[i];
            }
            return id[i];
        }
        boolean connected(int i, int j) {
            return root(i) == root(j);
        }
        boolean union(int i, int j) {
            int pi = root(i);
            int pj = root(j);
            if(pi == pj) return false;
            if(sz[pi] > sz[pj]) {
                id[pj] = id[pi];
                sz[pi] += sz[pj];
            } else {
                id[pi] = id[pj];
                sz[pj] += sz[pi];
            }
            return true;
        }
    }
    
    public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
        List<int[]> edges = new ArrayList<>();
        for(int i = 0; i < wells.length; i++) {
            edges.add(new int[]{0, i + 1, wells[i]});
        }
        for(int[] pipe : pipes) {
            edges.add(new int[]{pipe[0], pipe[1], pipe[2]});
        }
        Collections.sort(edges, (a, b) -> Integer.compare(a[2], b[2]));
        WQUPC qu = new WQUPC(n + 1);
        int res = 0;
        for(int[] edge : edges) {
            if(qu.union(edge[0], edge[1])) {
                // System.out.println(edge[0] + " " + edge[1] + " " + edge[2]);
                res += edge[2];
            }
        }
        return res;
    }
}

 

Guess you like

Origin www.cnblogs.com/rookielet/p/11415625.html