/// <summary> /// An edge was found which connects two 'even' vertices in the forest. If /// the vertices have the same root we have a blossom otherwise we have /// identified an augmenting path. This method checks for these cases and /// responds accordingly. /// <para> /// If an augmenting path was found - then it's edges are alternated and the /// method returns true. Otherwise if a blossom was found - it is contracted /// and the search continues. /// </para> /// </summary> /// <param name="v">endpoint of an edge</param> /// <param name="w">another endpoint of an edge</param> /// <returns>a path was augmented</returns> private bool Check(int v, int w) { // self-loop (within blossom) ignored if (uf.Connected(v, w)) { return(false); } vAncestors.SetAll(false); wAncestors.SetAll(false); int vCurr = v; int wCurr = w; // walk back along the trees filling up 'vAncestors' and 'wAncestors' // with the vertices in the tree - vCurr and wCurr are the 'even' parents // from v/w along the tree while (true) { vCurr = Parent(vAncestors, vCurr); wCurr = Parent(wAncestors, wCurr); // v and w lead to the same root - we have found a blossom. We // travelled all the way down the tree thus vCurr (and wCurr) are // the base of the blossom if (vCurr == wCurr) { Blossom(v, w, vCurr); return(false); } // we are at the root of each tree and the roots are different, we // have found and augmenting path if (uf.Find(even[vCurr]) == vCurr && uf.Find(even[wCurr]) == wCurr) { Augment(v); Augment(w); matching.Match(v, w); return(true); } // the current vertex in 'v' can be found in w's ancestors they must // share a root - we have found a blossom whose base is 'vCurr' if (wAncestors[vCurr]) { Blossom(v, w, vCurr); return(false); } // the current vertex in 'w' can be found in v's ancestors they must // share a root, we have found a blossom whose base is 'wCurr' if (vAncestors[wCurr]) { Blossom(v, w, wCurr); return(false); } } }
public void Connected() { UnionFind uf = new UnionFind(100); uf.Union(1, 5); uf.Union(7, 9); uf.Union(7, 5); uf.Union(10, 11); uf.Union(11, 50); uf.Union(15, 1); uf.Union(15, 50); Assert.IsTrue(uf.Connected(1, 5)); Assert.IsTrue(uf.Connected(1, 7)); Assert.IsTrue(uf.Connected(1, 9)); Assert.IsTrue(uf.Connected(1, 10)); Assert.IsTrue(uf.Connected(1, 11)); Assert.IsTrue(uf.Connected(1, 15)); Assert.IsTrue(uf.Connected(1, 50)); }