Пример #1
0
        /// <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);
                }
            }
        }
Пример #2
0
        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));
        }