// end the shortest Edge-disjoint augmenting paths.
// Side effect: For any Edge v.layer has the index of
// the BFS layer to reach this Edge (or -1)
// B: potential beginning of augmenting paths
Set<BipartiteNode<T>> Q = new FastSet(B);
// F: The set of free endings (the other side of augmenting paths)
Set<BipartiteNode<T>> F = FastSet.newInstance();
for (BipartiteNode<T> node : U) {
node.layer = -1;
}
for (BipartiteNode<T> node : V) {
node.layer = -1;
}
// The potential beginnings of augmenting paths are at layer 0.
for (BipartiteNode<T> node : B) {
node.layer = 0;
}
while (!Q.isEmpty()) {
Set<BipartiteNode<T>> G = FastSet.newInstance();
for (BipartiteNode<T> q : Q) {
for (Edge<BipartiteNode<T>> v : edges) {
if (v.getSource() == q || v.getTarget() == q) {
BipartiteNode<T> p;
if (v.getSource() == q)
p = v.getTarget();
else
// (v.getTarget() == q)
p = v.getSource();
if (p.layer == -1) {
p.layer = q.layer + 1;
if (p.matching == null)
// Collect the free Edge, continue BFS
F.add(p);
else
G.add(p);
}
}
}
}
if (!F.isEmpty())
// Free vertices found, stop at this layer.
return F;
Q.clear();
for (BipartiteNode<T> q : G) {
// By construction, q matched.
BipartiteNode<T> p = q.matching;
p.layer = q.layer + 1;
Q.add(p);
}
}
return FastSet.newInstance();
}