From 0c2340f789090ef7521a68125a718f37b624b45b Mon Sep 17 00:00:00 2001 From: ErdemT09 Date: Tue, 6 Jul 2021 15:45:47 +0300 Subject: [PATCH 1/4] 1168-Add Branch --- .../hard/OptimizeWaterDistributionInAVillage.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java diff --git a/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java b/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java new file mode 100644 index 00000000..4af16b35 --- /dev/null +++ b/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java @@ -0,0 +1,8 @@ +package algorithms.curated170.hard; + +import java.util.Arrays; + + +public class OptimizeWaterDistributionInAVillage { + +} From f78a1b08afa40710ee7b14a1f71f5cd28c09722a Mon Sep 17 00:00:00 2001 From: ErdemT09 Date: Tue, 6 Jul 2021 16:02:52 +0300 Subject: [PATCH 2/4] 1168-Add Union-Find Solution --- .../OptimizeWaterDistributionInAVillage.java | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java b/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java index 4af16b35..8778a911 100644 --- a/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java +++ b/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java @@ -1,8 +1,53 @@ package algorithms.curated170.hard; import java.util.Arrays; +import java.util.PriorityQueue; - public class OptimizeWaterDistributionInAVillage { - + public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); + parent = new int[n + 1]; + for (int i = 0; i < n; i++) { + pq.offer(new int[] { 0, i + 1, wells[i] }); + parent[i + 1] = i + 1; + } + for (int[] pipe : pipes) { + pq.offer(pipe); + } + + int com = n + 1; + int costs = 0; + while (com > 1) { + int[] edge = pq.poll(); + int a = edge[0], b = edge[1]; + int parA = find(a), parB = find(b); + if(parA == parB) + { + continue; + } + parent[parB] = parA; + com--; + costs += edge[2]; + } + return costs; + } + + int[] parent; + + int find(int k) { + if (k != parent[k]) { + parent[k] = find(parent[k]); + } + return parent[k]; + } + public static void main(String[] args) { + var solution = new OptimizeWaterDistributionInAVillage(); + + int[] wells = new int[]{1,2,2}; + int[][] pipes = new int[][]{ + {1,2,1}, + {2,3,1} + }; + System.out.println(solution.minCostToSupplyWater(3, wells, pipes)); + } } From d33e97cc6b733e4ec31f3daf3e22da21a153f416 Mon Sep 17 00:00:00 2001 From: ErdemT09 Date: Tue, 6 Jul 2021 17:06:27 +0300 Subject: [PATCH 3/4] 1168-Add Prim's Algorithm Solution --- ...timizeWaterDistributionInAVillagePrim.java | 83 +++++++++++++++++++ ...WaterDistributionInAVillageUnionFind.java} | 6 +- 2 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillagePrim.java rename src/main/java/algorithms/curated170/hard/{OptimizeWaterDistributionInAVillage.java => optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java} (86%) diff --git a/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillagePrim.java b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillagePrim.java new file mode 100644 index 00000000..0fd66ce4 --- /dev/null +++ b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillagePrim.java @@ -0,0 +1,83 @@ +package algorithms.curated170.hard.optimizewaterdistributioninavillage; + +import java.util.PriorityQueue; + +public class OptimizeWaterDistributionInAVillagePrim { + + public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { + + int[][][] graph = createGraph(n, wells, pipes); + + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[1] - b[1]); + for (int[] edge : graph[0]) { + pq.offer(edge); + } + + return getCostsMST(n, graph, pq); + } + + private int getCostsMST(int n, int[][][] graph, PriorityQueue pq) { + boolean[] visited = new boolean[n + 1]; + visited[0] = true; + int visitCount = 0; + int costs = 0; + + while (visitCount < n) { + int[] edge = pq.poll(); + + if (visited[edge[0]]) { + continue; + } + + visited[edge[0]] = true; + visitCount++; + costs += edge[1]; + + for (int[] newEdge : graph[edge[0]]) { + if (visited[newEdge[0]]) { + continue; + } + pq.offer(newEdge); + } + } + + return costs; + } + + private int[][][] createGraph(int n, int[] wells, int[][] edges) { + int[][][] graph = new int[n + 1][][]; + + graph[0] = new int[n][2]; + for (int i = 0; i < n; i++) { + graph[0][i][0] = i + 1; + graph[0][i][1] = wells[i]; + } + + int[] adjacentCount = new int[n + 1]; + for (int[] edge : edges) { + adjacentCount[edge[0]]++; + adjacentCount[edge[1]]++; + } + + for (int i = 1; i <= n; i++) { + graph[i] = new int[adjacentCount[i]][2]; + } + int[] currIdx = new int[n + 1]; + for (int[] edge : edges) { + graph[edge[0]][currIdx[edge[0]]][0] = edge[1]; + graph[edge[1]][currIdx[edge[1]]][0] = edge[0]; + graph[edge[0]][currIdx[edge[0]]++][1] = edge[2]; + graph[edge[1]][currIdx[edge[1]]++][1] = edge[2]; + } + return graph; + } + + public static void main(String[] args) { + var solution = new OptimizeWaterDistributionInAVillagePrim(); + + int[] wells = new int[] { 1, 2, 2 }; + int[][] pipes = new int[][] { { 1, 2, 1 }, { 2, 3, 1 } }; + System.out.println(solution.minCostToSupplyWater(3, wells, pipes)); + // The Graph: [[[1, 1], [2, 2], [3, 2]], [[2, 1]], [[1, 1], [3, 1]], [[2, 1]]] + } +} diff --git a/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java similarity index 86% rename from src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java rename to src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java index 8778a911..78ca3efc 100644 --- a/src/main/java/algorithms/curated170/hard/OptimizeWaterDistributionInAVillage.java +++ b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java @@ -1,9 +1,9 @@ -package algorithms.curated170.hard; +package algorithms.curated170.hard.optimizewaterdistributioninavillage; import java.util.Arrays; import java.util.PriorityQueue; -public class OptimizeWaterDistributionInAVillage { +public class OptimizeWaterDistributionInAVillageUnionFind { public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); parent = new int[n + 1]; @@ -41,7 +41,7 @@ int find(int k) { return parent[k]; } public static void main(String[] args) { - var solution = new OptimizeWaterDistributionInAVillage(); + var solution = new OptimizeWaterDistributionInAVillageUnionFind(); int[] wells = new int[]{1,2,2}; int[][] pipes = new int[][]{ From abf850e7994e1dfad2ee98c5f35019728b1b4ec4 Mon Sep 17 00:00:00 2001 From: ErdemT09 Date: Tue, 6 Jul 2021 17:18:42 +0300 Subject: [PATCH 4/4] 1168-Refactor Solution --- ...eWaterDistributionInAVillageUnionFind.java | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java index 78ca3efc..95084a53 100644 --- a/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java +++ b/src/main/java/algorithms/curated170/hard/optimizewaterdistributioninavillage/OptimizeWaterDistributionInAVillageUnionFind.java @@ -4,50 +4,71 @@ import java.util.PriorityQueue; public class OptimizeWaterDistributionInAVillageUnionFind { + + int[] parent; + int[] rank; + public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) { - PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); parent = new int[n + 1]; + rank = new int[n + 1]; + rank[0] = 1; + + PriorityQueue pq = createEdgesHeap(n, wells, pipes); + + return getConnectionCost(n, pq); + } + + private PriorityQueue createEdgesHeap(int n, int[] wells, int[][] pipes) { + PriorityQueue pq = new PriorityQueue<>((a, b) -> a[2] - b[2]); for (int i = 0; i < n; i++) { pq.offer(new int[] { 0, i + 1, wells[i] }); parent[i + 1] = i + 1; + rank[i + 1] = 1; } for (int[] pipe : pipes) { pq.offer(pipe); } + return pq; + } - int com = n + 1; + private int getConnectionCost(int n, PriorityQueue pq) { int costs = 0; - while (com > 1) { + int unconnected = n + 1; + + while (unconnected > 1) { int[] edge = pq.poll(); int a = edge[0], b = edge[1]; int parA = find(a), parB = find(b); - if(parA == parB) - { + + if (parA == parB) { continue; } - parent[parB] = parA; - com--; + + if (rank[parA] <= rank[parB]) { + parent[parA] = parB; + rank[parB] += rank[parA]; + } else { + parent[parB] = parA; + rank[parA] += rank[parB]; + } + unconnected--; costs += edge[2]; } return costs; } - int[] parent; - int find(int k) { if (k != parent[k]) { parent[k] = find(parent[k]); } return parent[k]; } + public static void main(String[] args) { var solution = new OptimizeWaterDistributionInAVillageUnionFind(); - int[] wells = new int[]{1,2,2}; - int[][] pipes = new int[][]{ - {1,2,1}, - {2,3,1} - }; + int[] wells = new int[] { 1, 2, 2 }; + int[][] pipes = new int[][] { { 1, 2, 1 }, { 2, 3, 1 } }; System.out.println(solution.minCostToSupplyWater(3, wells, pipes)); } }