1
- from collections import deque , defaultdict
1
+ from collections import defaultdict , deque
2
2
3
3
UNMATCHED = - 1 # Constant to represent unmatched vertices
4
4
5
5
6
6
class EdmondsBlossomAlgorithm :
7
7
@staticmethod
8
- def maximum_matching (edges : list [tuple [int , int ]], vertex_count : int ) -> list [tuple [int , int ]]:
8
+ def maximum_matching (
9
+ edges : list [tuple [int , int ]], vertex_count : int
10
+ ) -> list [tuple [int , int ]]:
9
11
"""
10
12
Finds the maximum matching in a general graph using Edmonds' Blossom Algorithm.
11
13
@@ -55,7 +57,8 @@ def maximum_matching(edges: list[tuple[int, int]], vertex_count: int) -> list[tu
55
57
continue # Avoid self-loops
56
58
57
59
if parent [neighbor ] == UNMATCHED :
58
- # Case 1: neighbor is unmatched, we've found an augmenting path
60
+ # Case 1: neighbor is unmatched, we've found
61
+ # an augmenting path
59
62
if match [neighbor ] == UNMATCHED :
60
63
parent [neighbor ] = current_vertex
61
64
augmenting_path_found = True
@@ -64,15 +67,17 @@ def maximum_matching(edges: list[tuple[int, int]], vertex_count: int) -> list[tu
64
67
)
65
68
break
66
69
67
- # Case 2: neighbor is matched, add neighbor's match to the queue
70
+ # Case 2: neighbor is matched, add neighbor's
71
+ # match to the queue
68
72
matched_vertex = match [neighbor ]
69
73
parent [neighbor ] = current_vertex
70
74
parent [matched_vertex ] = neighbor
71
75
if not in_queue [matched_vertex ]:
72
76
queue .append (matched_vertex )
73
77
in_queue [matched_vertex ] = True
74
78
else :
75
- # Case 3: Both current_vertex and neighbor have a parent; check for a cycle/blossom
79
+ # Case 3: Both current_vertex and neighbor
80
+ # have a parent; check for a cycle/blossom
76
81
base_vertex = EdmondsBlossomAlgorithm .find_base (
77
82
base , parent , current_vertex , neighbor
78
83
)
@@ -96,7 +101,9 @@ def maximum_matching(edges: list[tuple[int, int]], vertex_count: int) -> list[tu
96
101
return matching_result
97
102
98
103
@staticmethod
99
- def update_matching (match : list [int ], parent : list [int ], current_vertex : int ) -> None :
104
+ def update_matching (
105
+ match : list [int ], parent : list [int ], current_vertex : int
106
+ ) -> None :
100
107
"""
101
108
Updates the matching along the augmenting path found.
102
109
@@ -171,7 +178,9 @@ def contract_blossom(blossom_data: 'BlossomData') -> None:
171
178
current_vertex_u = blossom_data .u
172
179
while blossom_data .aux_data .base [current_vertex_u ] != blossom_data .lca :
173
180
base_u = blossom_data .aux_data .base [current_vertex_u ]
174
- match_base_u = blossom_data .aux_data .base [blossom_data .aux_data .match [current_vertex_u ]]
181
+ match_base_u = blossom_data .aux_data .base [
182
+ blossom_data .aux_data .match [current_vertex_u ]
183
+ ]
175
184
blossom_data .aux_data .in_blossom [base_u ] = True
176
185
blossom_data .aux_data .in_blossom [match_base_u ] = True
177
186
current_vertex_u = blossom_data .aux_data .parent [
@@ -181,7 +190,9 @@ def contract_blossom(blossom_data: 'BlossomData') -> None:
181
190
current_vertex_v = blossom_data .v
182
191
while blossom_data .aux_data .base [current_vertex_v ] != blossom_data .lca :
183
192
base_v = blossom_data .aux_data .base [current_vertex_v ]
184
- match_base_v = blossom_data .aux_data .base [blossom_data .aux_data .match [current_vertex_v ]]
193
+ match_base_v = blossom_data .aux_data .base [
194
+ blossom_data .aux_data .match [current_vertex_v ]
195
+ ]
185
196
blossom_data .aux_data .in_blossom [base_v ] = True
186
197
blossom_data .aux_data .in_blossom [match_base_v ] = True
187
198
current_vertex_v = blossom_data .aux_data .parent [
0 commit comments