1
- from collections import defaultdict , deque
1
+ from collections import deque , defaultdict
2
2
3
3
UNMATCHED = - 1 # Constant to represent unmatched vertices
4
4
5
5
6
6
class EdmondsBlossomAlgorithm :
7
7
@staticmethod
8
8
def maximum_matching (
9
- edges : list [tuple [int , int ]], vertex_count : int
9
+ edges : list [tuple [int , int ]], vertex_count : int
10
10
) -> list [tuple [int , int ]]:
11
11
"""
12
12
Finds the maximum matching in a general graph using Edmonds' Blossom Algorithm.
@@ -57,8 +57,7 @@ def maximum_matching(
57
57
continue # Avoid self-loops
58
58
59
59
if parent [neighbor ] == UNMATCHED :
60
- # Case 1: neighbor is unmatched, we've found
61
- # an augmenting path
60
+ # Case 1: neighbor is unmatched, we've found an augmenting path
62
61
if match [neighbor ] == UNMATCHED :
63
62
parent [neighbor ] = current_vertex
64
63
augmenting_path_found = True
@@ -67,28 +66,32 @@ def maximum_matching(
67
66
)
68
67
break
69
68
70
- # Case 2: neighbor is matched, add neighbor's
71
- # match to the queue
69
+ # Case 2: neighbor is matched, add neighbor's match to the queue
72
70
matched_vertex = match [neighbor ]
73
71
parent [neighbor ] = current_vertex
74
72
parent [matched_vertex ] = neighbor
75
73
if not in_queue [matched_vertex ]:
76
74
queue .append (matched_vertex )
77
75
in_queue [matched_vertex ] = True
78
76
else :
79
- # Case 3: Both current_vertex and neighbor
80
- # have a parent; check for a cycle/blossom
77
+ # Case 3: Both current_vertex and neighbor have a parent; check for a cycle/blossom
81
78
base_vertex = EdmondsBlossomAlgorithm .find_base (
82
79
base , parent , current_vertex , neighbor
83
80
)
84
81
if base_vertex != UNMATCHED :
85
82
EdmondsBlossomAlgorithm .contract_blossom (
86
83
BlossomData (
87
84
BlossomAuxData (
88
- queue , parent , base , in_blossom ,
89
- match , in_queue
85
+ queue ,
86
+ parent ,
87
+ base ,
88
+ in_blossom ,
89
+ match ,
90
+ in_queue ,
90
91
),
91
- current_vertex , neighbor , base_vertex
92
+ current_vertex ,
93
+ neighbor ,
94
+ base_vertex ,
92
95
)
93
96
)
94
97
@@ -102,7 +105,7 @@ def maximum_matching(
102
105
103
106
@staticmethod
104
107
def update_matching (
105
- match : list [int ], parent : list [int ], current_vertex : int
108
+ match : list [int ], parent : list [int ], current_vertex : int
106
109
) -> None :
107
110
"""
108
111
Updates the matching along the augmenting path found.
@@ -162,7 +165,7 @@ def find_base(
162
165
current_vertex_v = parent [current_vertex_v ]
163
166
164
167
@staticmethod
165
- def contract_blossom (blossom_data : ' BlossomData' ) -> None :
168
+ def contract_blossom (blossom_data : " BlossomData" ) -> None :
166
169
"""
167
170
Contracts a blossom in the graph, modifying the base array
168
171
and marking the vertices involved.
@@ -214,8 +217,13 @@ class BlossomAuxData:
214
217
"""
215
218
216
219
def __init__ (
217
- self , queue : deque , parent : list [int ], base : list [int ], in_blossom : list [bool ],
218
- match : list [int ], in_queue : list [bool ]
220
+ self ,
221
+ queue : deque ,
222
+ parent : list [int ],
223
+ base : list [int ],
224
+ in_blossom : list [bool ],
225
+ match : list [int ],
226
+ in_queue : list [bool ],
219
227
) -> None :
220
228
self .queue = queue
221
229
self .parent = parent
0 commit comments