#1579

Remove Max Number of Edges to Keep Graph Fully Traversable

Hard
Union-FindGraph TheoryUnion-FindGraph Traversal
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(n log n)
Space
O(1)
O(n)
💡

Intuition

Time O(n log n)Space O(n)

The optimal solution uses a Union-Find (Disjoint Set Union) data structure to efficiently manage connectivity between nodes. By prioritizing edges that both Alice and Bob can traverse, we can ensure maximum edge removal while maintaining full connectivity.

⚙️

Algorithm

4 steps
  1. 1Step 1: Sort edges by type, prioritizing type 3 edges first, then type 1, and finally type 2.
  2. 2Step 2: Use Union-Find to connect nodes based on the edges.
  3. 3Step 3: Count the number of edges used and check if both Alice and Bob can traverse all nodes.
  4. 4Step 4: Calculate the maximum removable edges based on the total edges and the edges used.
solution.py51 lines
1# Full working Python code
2class UnionFind:
3    def __init__(self, size):
4        self.parent = list(range(size))
5        self.rank = [1] * size
6
7    def find(self, u):
8        if self.parent[u] != u:
9            self.parent[u] = self.find(self.parent[u])
10        return self.parent[u]
11
12    def union(self, u, v):
13        rootU = self.find(u)
14        rootV = self.find(v)
15        if rootU != rootV:
16            if self.rank[rootU] > self.rank[rootV]:
17                self.parent[rootV] = rootU
18            elif self.rank[rootU] < self.rank[rootV]:
19                self.parent[rootU] = rootV
20            else:
21                self.parent[rootV] = rootU
22                self.rank[rootU] += 1
23
24
25def max_edges_to_remove(n, edges):
26    ufAlice = UnionFind(n + 1)
27    ufBob = UnionFind(n + 1)
28    totalEdges = len(edges)
29    usedEdges = 0
30
31    # Sort edges by type
32    edges.sort(key=lambda x: -x[0])
33
34    for edge in edges:
35        if edge[0] == 3:
36            ufAlice.union(edge[1], edge[2])
37            ufBob.union(edge[1], edge[2])
38            usedEdges += 1
39        elif edge[0] == 1:
40            ufAlice.union(edge[1], edge[2])
41            usedEdges += 1
42        elif edge[0] == 2:
43            ufBob.union(edge[1], edge[2])
44            usedEdges += 1
45
46    # Check if both can traverse
47    if ufAlice.find(1) != ufAlice.find(n) or ufBob.find(1) != ufBob.find(n):
48        return -1
49
50    return totalEdges - usedEdges
51

Complexity note: The sorting step dominates the time complexity, while the Union-Find operations are nearly constant time due to path compression.

  • 1Prioritize edges that can be traversed by both Alice and Bob to maximize removable edges.
  • 2Use Union-Find to efficiently manage connectivity between nodes.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.