private void ValidatesATree2(WeightedRootedTree <int> tree)
 {
     Assert.AreEqual(1, tree.VertexCount);
     Assert.AreEqual(0, tree.Vertices[0].Children.Count);
     Assert.AreEqual(0, tree.Vertices[0].Depth);
     Assert.AreEqual(1, tree.Vertices[0].SubtreeSize);
 }
예제 #2
0
 // https://blog.anudeep2011.com/heavy-light-decomposition/
 // https://www.geeksforgeeks.org/heavy-light-decomposition-set-2-implementation/
 public QTREE(int vertexCount, int[,] edges)
 {
     _edges                = edges;
     _tree                 = WeightedRootedTree.CreateFromEdges(vertexCount, rootID: 0, edges: edges);
     _eulerTour            = _tree.GetEulerTour();
     _eulerTourSegmentTree = new ArrayBasedSegmentTree <MinimumDepthQueryObject, Vertex>(_eulerTour);
     _tree.RunHLD();
     _hldBaseArraySegmentTree = new ArrayBasedSegmentTree <MaximumWeightQueryObject, Vertex>(_tree.HLDBaseArray);
 }
        public void GetEulerTour2()
        {
            var tree = WeightedRootedTree <int> .CreateFromEdges(1, 0, new int[, ] {
            });

            var eulerTour = tree.GetEulerTour();

            CollectionAssert.AreEqual(new[] { 0 }, eulerTour.Select(v => v.ID).ToArray());
            Assert.AreEqual(0, tree.Vertices[0].Depth);
        }
        public void ValidatesATree2()
        {
            var tree = WeightedRootedTree <int> .CreateFromChildren(1, 0, new List <KeyValuePair <int, int> >[] { null });

            tree.InitializeDepthsAndSubtreeSizes();
            ValidatesATree2(tree);

            tree = WeightedRootedTree <int> .CreateFromEdges(1, 0, new int[, ] {
            });

            ValidatesATree2(tree);
        }
        public void GetEulerTour3()
        {
            var tree = WeightedRootedTree <int> .CreateFromEdges(3, 0, new[, ]
            {
                { 2, 1, 11 },
                { 1, 0, 10 }
            });

            var eulerTour = tree.GetEulerTour();

            CollectionAssert.AreEqual(new[] { 0, 1, 2, 1, 0 }, eulerTour.Select(v => v.ID).ToArray());
            Assert.AreEqual(0, tree.Vertices[0].Depth);
            Assert.AreEqual(1, tree.Vertices[1].Depth);
            Assert.AreEqual(2, tree.Vertices[2].Depth);
        }
 private void ValidatesATree3(WeightedRootedTree <int> tree)
 {
     Assert.AreEqual(3, tree.VertexCount);
     Assert.AreEqual(1, tree.Vertices[0].Children.Count);
     Assert.AreEqual(1, tree.Vertices[0].Children[0].ID);
     Assert.AreEqual(1, tree.Vertices[1].Children.Count);
     Assert.AreEqual(2, tree.Vertices[1].Children[0].ID);
     Assert.AreEqual(0, tree.Vertices[2].Children.Count);
     Assert.AreEqual(0, tree.Vertices[0].Depth);
     Assert.AreEqual(1, tree.Vertices[1].Depth);
     Assert.AreEqual(2, tree.Vertices[2].Depth);
     Assert.AreEqual(3, tree.Vertices[0].SubtreeSize);
     Assert.AreEqual(2, tree.Vertices[1].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[2].SubtreeSize);
     Assert.AreEqual(null, tree.Vertices[0].Parent);
     Assert.AreEqual(10, tree.Vertices[1].Weight);
     Assert.AreEqual(11, tree.Vertices[2].Weight);
 }
예제 #7
0
    // For example, edges like (0, 1, 99), (1, 2, -3) => there's an edge between vertices 0 and 1 and 1 and 2.
    public static WeightedRootedTree CreateFromEdges(int vertexCount, int rootID, int[,] edges)
    {
        var tree = new WeightedRootedTree(vertexCount, rootID);

        for (int i = 0; i < vertexCount - 1; ++i)
        {
            var firstVertex  = tree.Vertices[edges[i, 0]];
            var secondVertex = tree.Vertices[edges[i, 1]];
            int weight       = edges[i, 2];
            firstVertex.AddNeighbor(secondVertex, weight);
            secondVertex.AddNeighbor(firstVertex, weight);
        }

        // Now we need to wire up the parent-child relationships. We have to DFS, so we
        // might as well initialize depths and subtree sizes at the same time.
        var verticesToVisit = new Stack <Vertex>();

        verticesToVisit.Push(tree.Root);

        while (verticesToVisit.Count > 0)
        {
            var vertex = verticesToVisit.Peek();

            // If Depth is null, it's the first time we're visiting the vertex. Visit its children.
            if (!vertex.Depth.HasValue)
            {
                vertex.Depth = 1 + (vertex.Parent?.Depth ?? -1);

                foreach (var childEdge in vertex.NeighborEdges.Where(ne => ne.Key != vertex.Parent))
                {
                    childEdge.Key.SetParent(vertex, childEdge.Value);
                    verticesToVisit.Push(childEdge.Key);
                }
            }
            // At this point, we know all the children have been visited, so we're good to pop.
            else
            {
                verticesToVisit.Pop();
                vertex.SubtreeSize = 1 + vertex.Children.Sum(c => c.SubtreeSize);
            }
        }

        return(tree);
    }
        public void RunHLD()
        {
            // This is the tree pictured here (but zero-based):
            // https://www.geeksforgeeks.org/heavy-light-decomposition-set-2-implementation/.
            var tree = WeightedRootedTree <int> .CreateFromEdges(11, 0, new[, ]
            {
                { 0, 1, 13 }, { 0, 2, 9 }, { 0, 3, 23 },
                { 1, 4, 4 }, { 1, 5, 25 },
                { 2, 6, 29 },
                { 5, 7, 5 },
                { 6, 8, 30 },
                { 7, 9, 1 }, { 7, 10, 6 }
            });

            tree.RunHLD();

            CollectionAssert.AreEqual(new[] { 0, 10, 4, 2, 3 }, tree.HLDChainHeads.Select(v => v.ID).ToArray());
            Assert.AreEqual(0, tree.Vertices[0].HLDChainIndex);
            Assert.AreEqual(0, tree.Vertices[1].HLDChainIndex);
            Assert.AreEqual(0, tree.Vertices[5].HLDChainIndex);
            Assert.AreEqual(0, tree.Vertices[7].HLDChainIndex);
            Assert.AreEqual(0, tree.Vertices[9].HLDChainIndex);
            Assert.AreEqual(1, tree.Vertices[10].HLDChainIndex);
            Assert.AreEqual(2, tree.Vertices[4].HLDChainIndex);
            Assert.AreEqual(3, tree.Vertices[2].HLDChainIndex);
            Assert.AreEqual(3, tree.Vertices[6].HLDChainIndex);
            Assert.AreEqual(3, tree.Vertices[8].HLDChainIndex);
            Assert.AreEqual(4, tree.Vertices[3].HLDChainIndex);

            CollectionAssert.AreEqual(
                new[] { 0, 1, 5, 7, 9, 10, 4, 2, 6, 8, 3 },
                tree.HLDBaseArray.Select(v => v.ID).ToArray());
            Assert.AreEqual(0, tree.Vertices[0].HLDBaseArrayIndex);
            Assert.AreEqual(1, tree.Vertices[1].HLDBaseArrayIndex);
            Assert.AreEqual(2, tree.Vertices[5].HLDBaseArrayIndex);
            Assert.AreEqual(3, tree.Vertices[7].HLDBaseArrayIndex);
            Assert.AreEqual(4, tree.Vertices[9].HLDBaseArrayIndex);
            Assert.AreEqual(5, tree.Vertices[10].HLDBaseArrayIndex);
            Assert.AreEqual(6, tree.Vertices[4].HLDBaseArrayIndex);
            Assert.AreEqual(7, tree.Vertices[2].HLDBaseArrayIndex);
            Assert.AreEqual(8, tree.Vertices[6].HLDBaseArrayIndex);
            Assert.AreEqual(9, tree.Vertices[8].HLDBaseArrayIndex);
            Assert.AreEqual(10, tree.Vertices[3].HLDBaseArrayIndex);
        }
        public void ValidatesATree1()
        {
            // This is the tree pictured here (but zero-based w/ weights): https://www.spoj.com/problems/LCA/.
            var tree = WeightedRootedTree <int> .CreateFromChildren(13, 0, new[]
            {
                new List <KeyValuePair <int, int> > {
                    KVP(1, 1), KVP(2, 2), KVP(3, 3)
                },
                null,
                new List <KeyValuePair <int, int> > {
                    KVP(4, -1), KVP(5, -2), KVP(6, -3)
                },
                null,
                null,
                new List <KeyValuePair <int, int> > {
                    KVP(7, 0), KVP(8, 10)
                },
                new List <KeyValuePair <int, int> > {
                    KVP(9, 1), KVP(10, 2)
                },
                null,
                null,
                new List <KeyValuePair <int, int> > {
                    KVP(11, 3), KVP(12, 4)
                },
                null,
                null,
                null
            });

            tree.InitializeDepthsAndSubtreeSizes();
            ValidatesATree1(tree);

            tree = WeightedRootedTree <int> .CreateFromEdges(13, 0, new[, ]
            {
                { 0, 1, 1 }, { 0, 2, 2 }, { 0, 3, 3 },
                { 2, 4, -1 }, { 2, 5, -2 }, { 2, 6, -3 },
                { 9, 6, 1 }, { 10, 6, 2 },
                { 5, 7, 0 }, { 5, 8, 10 },
                { 9, 11, 3 }, { 9, 12, 4 }
            });

            ValidatesATree1(tree);
        }
        public void GetEulerTour1()
        {
            // This is the tree pictured here (but zero-based w/ weights): https://www.spoj.com/problems/LCA/.
            var tree = WeightedRootedTree <int> .CreateFromEdges(13, 0, new[, ]
            {
                { 0, 1, 1 }, { 0, 2, 2 }, { 0, 3, 3 },
                { 2, 4, -1 }, { 2, 5, -2 }, { 2, 6, -3 },
                { 9, 6, 1 }, { 10, 6, 2 },
                { 5, 7, 0 }, { 5, 8, 10 },
                { 9, 11, 3 }, { 9, 12, 4 }
            });

            var eulerTour = tree.GetEulerTour();

            CollectionAssert.AreEqual(
                new[] { 0, 1, 0, 2, 4, 2, 5, 7, 5, 8, 5, 2, 6, 9, 11, 9, 12, 9, 6, 10, 6, 2, 0, 3, 0 },
                eulerTour.Select(v => v.ID).ToArray());
            Assert.AreEqual(0, tree.Vertices[0].EulerTourInitialIndex);
            Assert.AreEqual(1, tree.Vertices[1].EulerTourInitialIndex);
            Assert.AreEqual(3, tree.Vertices[2].EulerTourInitialIndex);
            Assert.AreEqual(4, tree.Vertices[4].EulerTourInitialIndex);
            Assert.AreEqual(6, tree.Vertices[5].EulerTourInitialIndex);
            Assert.AreEqual(14, tree.Vertices[11].EulerTourInitialIndex);
            Assert.AreEqual(0, tree.Vertices[0].Depth);
            Assert.AreEqual(1, tree.Vertices[1].Depth);
            Assert.AreEqual(1, tree.Vertices[2].Depth);
            Assert.AreEqual(1, tree.Vertices[3].Depth);
            Assert.AreEqual(2, tree.Vertices[4].Depth);
            Assert.AreEqual(2, tree.Vertices[5].Depth);
            Assert.AreEqual(2, tree.Vertices[6].Depth);
            Assert.AreEqual(3, tree.Vertices[7].Depth);
            Assert.AreEqual(3, tree.Vertices[8].Depth);
            Assert.AreEqual(3, tree.Vertices[9].Depth);
            Assert.AreEqual(3, tree.Vertices[10].Depth);
            Assert.AreEqual(4, tree.Vertices[11].Depth);
            Assert.AreEqual(4, tree.Vertices[12].Depth);
        }
        public void ValidatesATree3()
        {
            var tree = WeightedRootedTree <int> .CreateFromChildren(3, 0, new[]
            {
                new List <KeyValuePair <int, int> > {
                    KVP(1, 10)
                },
                new List <KeyValuePair <int, int> > {
                    KVP(2, 11)
                },
                null
            });

            tree.InitializeDepthsAndSubtreeSizes();
            ValidatesATree3(tree);

            tree = WeightedRootedTree <int> .CreateFromEdges(3, 0, new[, ]
            {
                { 2, 1, 11 },
                { 1, 0, 10 }
            });

            ValidatesATree3(tree);
        }
예제 #12
0
 internal Vertex(WeightedRootedTree tree, int ID)
 {
     _tree   = tree;
     this.ID = ID;
 }
 private void ValidatesATree1(WeightedRootedTree <int> tree)
 {
     Assert.AreEqual(13, tree.VertexCount);
     CollectionAssert.AreEquivalent(
         new[] { 1, 2, 3 }, tree.Vertices[0].Children.Select(c => c.ID).ToArray());
     Assert.AreEqual(0, tree.Vertices[1].Children.Count);
     CollectionAssert.AreEquivalent(
         new[] { 4, 5, 6 }, tree.Vertices[2].Children.Select(c => c.ID).ToArray());
     Assert.AreEqual(0, tree.Vertices[3].Children.Count);
     Assert.AreEqual(0, tree.Vertices[4].Children.Count);
     CollectionAssert.AreEquivalent(
         new[] { 7, 8 }, tree.Vertices[5].Children.Select(c => c.ID).ToArray());
     CollectionAssert.AreEquivalent(
         new[] { 9, 10 }, tree.Vertices[6].Children.Select(c => c.ID).ToArray());
     Assert.AreEqual(0, tree.Vertices[7].Children.Count);
     Assert.AreEqual(0, tree.Vertices[8].Children.Count);
     CollectionAssert.AreEquivalent(
         new[] { 11, 12 }, tree.Vertices[9].Children.Select(c => c.ID).ToArray());
     Assert.AreEqual(0, tree.Vertices[10].Children.Count);
     Assert.AreEqual(0, tree.Vertices[11].Children.Count);
     Assert.AreEqual(0, tree.Vertices[12].Children.Count);
     Assert.AreEqual(0, tree.Vertices[0].Depth);
     Assert.AreEqual(1, tree.Vertices[1].Depth);
     Assert.AreEqual(1, tree.Vertices[2].Depth);
     Assert.AreEqual(1, tree.Vertices[3].Depth);
     Assert.AreEqual(2, tree.Vertices[4].Depth);
     Assert.AreEqual(2, tree.Vertices[5].Depth);
     Assert.AreEqual(2, tree.Vertices[6].Depth);
     Assert.AreEqual(3, tree.Vertices[7].Depth);
     Assert.AreEqual(3, tree.Vertices[8].Depth);
     Assert.AreEqual(3, tree.Vertices[9].Depth);
     Assert.AreEqual(3, tree.Vertices[10].Depth);
     Assert.AreEqual(4, tree.Vertices[11].Depth);
     Assert.AreEqual(4, tree.Vertices[12].Depth);
     Assert.AreEqual(13, tree.Vertices[0].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[1].SubtreeSize);
     Assert.AreEqual(10, tree.Vertices[2].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[3].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[4].SubtreeSize);
     Assert.AreEqual(3, tree.Vertices[5].SubtreeSize);
     Assert.AreEqual(5, tree.Vertices[6].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[7].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[8].SubtreeSize);
     Assert.AreEqual(3, tree.Vertices[9].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[10].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[11].SubtreeSize);
     Assert.AreEqual(1, tree.Vertices[12].SubtreeSize);
     Assert.AreEqual(null, tree.Vertices[0].Parent);
     Assert.AreEqual(1, tree.Vertices[1].Weight);
     Assert.AreEqual(2, tree.Vertices[2].Weight);
     Assert.AreEqual(3, tree.Vertices[3].Weight);
     Assert.AreEqual(-1, tree.Vertices[4].Weight);
     Assert.AreEqual(-2, tree.Vertices[5].Weight);
     Assert.AreEqual(-3, tree.Vertices[6].Weight);
     Assert.AreEqual(0, tree.Vertices[7].Weight);
     Assert.AreEqual(10, tree.Vertices[8].Weight);
     Assert.AreEqual(1, tree.Vertices[9].Weight);
     Assert.AreEqual(2, tree.Vertices[10].Weight);
     Assert.AreEqual(3, tree.Vertices[11].Weight);
     Assert.AreEqual(4, tree.Vertices[12].Weight);
 }