@@ -18,9 +18,13 @@ def __init__(self, num_vertices: int):
1818 Args:
1919 num_vertices: The number of vertices to generate in the graph.
2020 """
21- self .vertices = list (range (num_vertices ))
21+ self .vertices : list [ int ] = list (range (num_vertices ))
2222 # [(vertex_1, vertex_2, weight)]
23- self .edges = []
23+ self .edges : list [tuple [int , int , int ]] = []
24+ # Each node is its own parent initially.
25+ self .parent : list [int ] = list (range (num_vertices ))
26+ # Each tree has size 1 (itself) initially.
27+ self .rank : list [int ] = [1 ] * num_vertices
2428
2529 def add_edge (self , vertex_1 : int , vertex_2 : int , weight : int ) -> None :
2630 """
@@ -47,6 +51,54 @@ def print_graph_info(self) -> None:
4751 for edge in sorted (self .edges ):
4852 print (f" { edge } " )
4953
54+ def find (self , node : int ) -> int :
55+ """
56+ Finds the root parent of the node using path compression.
57+
58+ Args:
59+ node: The node to find the root parent of.
60+
61+ Returns:
62+ The root parent of the node.
63+ """
64+ cur_parent = self .parent [node ]
65+ while cur_parent != self .parent [cur_parent ]:
66+ # Compress the links as we go up the chain of parents to make
67+ # it faster to traverse in the future - amortised O(a(n)) time,
68+ # where a(n) is the inverse Ackermann function.
69+ self .parent [cur_parent ] = self .parent [self .parent [cur_parent ]]
70+ cur_parent = self .parent [cur_parent ]
71+
72+ return cur_parent
73+
74+ def union (self , node1 : int , node2 : int ) -> bool :
75+ """
76+ Combines the two nodes into the larger segment.
77+
78+ Args:
79+ node1: The first node to combine.
80+ node2: The second node to combine.
81+
82+ Returns:
83+ True if the nodes were combined, False if they were already in the
84+ same segment.
85+ """
86+ root1 = self .find (node1 )
87+ root2 = self .find (node2 )
88+ # If they have the same root parent, a cycle exists.
89+ if root1 == root2 :
90+ return False
91+
92+ # Combine the two nodes into the larger segment based on the rank.
93+ if self .rank [root1 ] > self .rank [root2 ]:
94+ self .parent [root2 ] = root1
95+ self .rank [root1 ] += self .rank [root2 ]
96+ else :
97+ self .parent [root1 ] = root2
98+ self .rank [root2 ] += self .rank [root1 ]
99+
100+ return True
101+
50102 def merge_components (
51103 self ,
52104 vertex_to_component : Dict [int , int ],
0 commit comments