@@ -62,38 +62,52 @@ namespace MaximumBipartiteMatching
6262 this ->_noOfVertices = newNoOfVertices;
6363 }
6464
65+ // This method is used to color the vertices of the graph to determine if the given graph is bipartite or not
6566 void Graph::ColorGraph ()
6667 {
6768 // Color of all the vertices are initialised to WHITE
6869 fill (this ->_color .begin (), this ->_color .end (), WHITE);
6970
71+ // Queue to hold the vertices
7072 queue<int > nodeQueue;
7173
7274 for (int node = 0 ; node < this ->_noOfVertices ; node++)
7375 {
76+ // Check if the node is already not colored
7477 if (this ->_color [node] == WHITE)
7578 {
79+ // The color of the node is set to RED
7680 this ->_color [node] = RED;
81+
82+ // The node is inserted into the queue
7783 nodeQueue.push (node);
7884
85+ // Using BFS method to color all the vertices
7986 while (!nodeQueue.empty ())
8087 {
8188 int nodeU = nodeQueue.front ();
8289 nodeQueue.pop ();
8390
91+ // Iterating over G.Adj[nodeU]
8492 for (int nodeV = 0 ; nodeV < this ->_noOfVertices ; nodeV++)
8593 {
94+ // As there are no self loops, continue
8695 if (nodeU == nodeV)
8796 {
8897 continue ;
8998 }
99+ // Check if there is an edge u --> v and nodeV is not colored yet
90100 else if (this ->_residualGraph [nodeU][nodeV] != 0 && this ->_color [nodeV] == WHITE)
91101 {
102+ // Set the color of nodeV opposite of nodeU
92103 this ->_color [nodeV] = 1 - this ->_color [nodeU];
104+ // Insert the nodeV into the queue
93105 nodeQueue.push (nodeV);
94106 }
107+ // Check if there is an edge u --> v and nodeV is of same color as nodeU
95108 else if (this ->_residualGraph [nodeU][nodeV] != 0 && this ->_color [nodeV] == this ->_color [nodeU])
96109 {
110+ // Set the _isBipartite flag to false and return
97111 this ->_isBipartite = false ;
98112 return ;
99113 }
@@ -102,33 +116,46 @@ namespace MaximumBipartiteMatching
102116 }
103117 }
104118
119+ // If the above operation completes without returning yet that indicates the graph is bipartite
120+ // Set the _isBipartite flag to true and return
105121 this ->_isBipartite = true ;
106122 return ;
107123 }
108124
125+ // This method is used to create the additional edges
126+ // from the source vertex to the RED colored vertices and
127+ // from the BLUE colored vertices to the sink vertex
109128 void Graph::AddAdditionalEdges ()
110129 {
130+ // Resizing the residual graph to accomodate space for the new edges
111131 for (auto & edge : this ->_residualGraph )
112132 {
113133 edge.resize (this ->_noOfVertices , 0 );
114134 }
135+
115136 this ->_parent .resize (this ->_noOfVertices , -1 );
116137 this ->_visited .resize (this ->_noOfVertices , false );
117138 this ->_color .resize (this ->_noOfVertices , WHITE);
118139 this ->_residualGraph .resize (this ->_noOfVertices , vector<int >(this ->_noOfVertices , 0 ));
140+
141+ // Creating the additional edges
119142 for (int node = 0 ; node < this ->_source ; node++)
120143 {
144+ // From source vertex --> RED colored vertices
121145 if (this ->_color [node] == RED)
122146 {
123147 this ->_residualGraph [this ->_source ][node] = 1 ;
124148 }
149+
150+ // From BLUE colored vertices --> sink vertex
125151 else if (this ->_color [node] == BLUE)
126152 {
127153 this ->_residualGraph [node][this ->_sink ] = 1 ;
128154 }
129155 }
130156 }
131157
158+ // Implementation of BreadthFirstSearch for EdmondsKarp algorithm to find the path from source to sink
132159 bool Graph::BreadthFirstSearch ()
133160 {
134161 // Resetting the visited values
@@ -198,6 +225,8 @@ namespace MaximumBipartiteMatching
198225 {
199226 int augmentedPathFlow = 1 ;
200227
228+ // No need to find the minimum amount of augmentedPathFlow as like standard EdmondsKarp algorithm
229+ // as here capacity of each edges is 1
201230 for (int nodeV = this ->_sink ; nodeV != this ->_source ; nodeV = this ->_parent [nodeV])
202231 {
203232 int nodeU = this ->_parent [nodeV];
@@ -210,12 +239,16 @@ namespace MaximumBipartiteMatching
210239 return this ->_maximumFlow ;
211240 }
212241
242+ // This method is used for finding the matchings
213243 vector<vector<int >> Graph::GetMatchings ()
214244 {
215245 for (int nodeU = 0 ; nodeU < this ->_adjMatrix .size (); nodeU++)
216246 {
217247 for (int nodeV = 0 ; nodeV < this ->_adjMatrix .size (); nodeV++)
218248 {
249+ // Check if the nodeU and nodeV are not source or sink
250+ // and there is a flow of 1 unit from nodeU --> nodeV
251+ // which means nodeU --> nodeV is being used for the maximum flow (maximum matching)
219252 if ((nodeU != this ->_source || nodeU != this ->_sink || nodeV != this ->_source || nodeV != this ->_sink )
220253 &&
221254 (this ->_adjMatrix [nodeU][nodeV] - this ->_residualGraph [nodeU][nodeV]) == 1 )
0 commit comments