From 2cff21483da0311e51b3a535ff13de8b7c800e84 Mon Sep 17 00:00:00 2001 From: 7oSkaaa Date: Sun, 30 Apr 2023 00:53:32 +0000 Subject: [PATCH] Add new daily problem to README --- 04- April/README.md | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/04- April/README.md b/04- April/README.md index 10fcc20f1..0e2635750 100644 --- a/04- April/README.md +++ b/04- April/README.md @@ -51,6 +51,7 @@ 1. **[Add Digits](#26--add-digits)** 1. **[Bulb Switcher](#27--bulb-switcher)** 1. **[Similar String Groups](#28--similar-string-groups)** +1. **[Remove Max Number of Edges to Keep Graph Fully Traversable](#30--remove-max-number-of-edges-to-keep-graph-fully-traversable)**


@@ -1631,4 +1632,97 @@ public: }; ``` + +
+

+ +## 30) [Remove Max Number of Edges to Keep Graph Fully Traversable](https://leetcode.com/problems/remove-max-number-of-edges-to-keep-graph-fully-traversable/) + +### Difficulty + +![](https://img.shields.io/badge/Hard-red?style=for-the-badge) + +### Related Topic + +`Union Find` `Graph` + +### Code + + +```cpp +// Define a generic disjoint-set union data structure with an optional base node +// parameter for 1-based indexing, and a template parameter for data type T. +template +struct DSU { + // The parent vector stores the parent of each node, and the Gsize vector + // stores the size of each disjoint set. + vector parent, Gsize; + + // Constructor initializes the parent and Gsize vectors for all nodes. + DSU(int MaxNodes) { + parent = Gsize = vector(MaxNodes + 5); + for (int i = Base; i <= MaxNodes; i++) + parent[i] = i, Gsize[i] = 1; + } + + // Recursive function to find the leader of the disjoint set that the node + // belongs to, and updates the parent of all visited nodes to the leader. + T find_leader(int node) { + return parent[node] = (parent[node] == node ? node : find_leader(parent[node])); + } + + // Returns true if the two nodes belong to the same disjoint set. + bool is_same_sets(int u, int v) { + return find_leader(u) == find_leader(v); + } + + // Merges the disjoint sets containing the two nodes u and v. + void union_sets(int u, int v) { + int leader_u = find_leader(u), leader_v = find_leader(v); + if (leader_u == leader_v) return; + if (Gsize[leader_u] < Gsize[leader_v]) swap(leader_u, leader_v); + Gsize[leader_u] += Gsize[leader_v], parent[leader_v] = leader_u; + } + + // Returns the size of the disjoint set that the node belongs to. + int get_size(int u) { + return Gsize[find_leader(u)]; + } +}; + +class Solution { +public: + int maxNumEdgesToRemove(int n, vector>& edges) { + // Variable to store the number of edges removed. + int removed_edges = 0; + // Create two disjoint-set union objects, one for Alice and one for Bob. + DSU alice(n), bob(n); + // Sort edges in decreasing order of type so that type 3 edges are + // processed last. + sort(edges.rbegin(), edges.rend()); + // Loop through each edge in the sorted list. + for (auto& edge : edges) { + int t = edge[0], u = edge[1], v = edge[2]; + // Process the edge based on its type. + if (t == 1) { + if (alice.is_same_sets(u, v)) removed_edges++; + else alice.union_sets(u, v); + } else if (t == 2) { + if (bob.is_same_sets(u, v)) removed_edges++; + else bob.union_sets(u, v); + } else { + if (alice.is_same_sets(u, v) && bob.is_same_sets(u, v)) removed_edges++; + else alice.union_sets(u, v), bob.union_sets(u, v); + } + } + // Check if all nodes belong to the same disjoint set for both Alice and + // Bob. If not, return -1 as it is impossible to remove enough edges to + // create a spanning tree for both players. + if (alice.get_size(1) != n || bob.get_size(1) != n) + return -1; + // Return the number of edges removed. + return removed_edges; + } +}; +``` \ No newline at end of file