Beispiel #1
0
        private HLDTreeNode FindLCA(HLDTreeNode p, HLDTreeNode q)
        {
            if (p.depth < q.depth)
            {
                var t = p;
                p = q;
                q = t;
            }

            if (p.segId == q.segId)
            {
                //on same segment tree
                return(q);
            }

            var pa = segNodes[p.segId][0];

            if (pa.depth >= q.depth)
            {
                return(FindLCA(pa.parent, q));
            }

            var qa = segNodes[q.segId][0];

            if (qa.depth <= pa.depth)
            {
                return(FindLCA(pa.parent, qa.parent));
            }

            return(FindLCA(p, qa.parent));
        }
Beispiel #2
0
        private void BuildTree(List <int[]> edges)
        {
            var N           = edges.Count;
            var sortedEdges = new List <int[]> [N + 1];

            for (int i = 0; i < N; i++)
            {
                if (sortedEdges[edges[i][0] - 1] == null)
                {
                    sortedEdges[edges[i][0] - 1] = new List <int[]>();
                }
                sortedEdges[edges[i][0] - 1].Add(new int[2] {
                    edges[i][1], edges[i][2]
                });
            }

            var nodeIdStack = new Stack <int>();

            nodeIdStack.Push(0);
            var parentStack = new Stack <HLDTreeNode>();

            parentStack.Push(root);

            while (nodeIdStack.Count > 0)
            {
                var id     = nodeIdStack.Pop();
                var parent = parentStack.Pop();
                if (sortedEdges[id] == null)
                {
                    //leaf
                    continue;
                }

                foreach (var edge in sortedEdges[id])
                {
                    var node = new HLDTreeNode
                    {
                        id       = edge[0] - 1,
                        parent   = parent,
                        children = new List <HLDTreeNode>(),
                        value    = edge[1],
                        depth    = parent.depth + 1
                    };


                    nodes[edge[0] - 1] = node;
                    parent.children.Add(node);
                    parent.size++;
                    nodeIdStack.Push(edge[0] - 1);
                    parentStack.Push(node);
                }
            }

            //Currently all size is the number of its direct children, update
            UpdateSize(root);
        }
Beispiel #3
0
 private int GetMaxEdge(HLDTreeNode start, HLDTreeNode end)
 {
     if (start.segId != end.segId)
     {
         var max = segTrees[start.segId].GetCombine(0, start.segPos);
         return(Math.Max(max, GetMaxEdge(segNodes[start.segId][0].parent, end)));
     }
     else
     {
         if (end.segPos == start.segPos)
         {
             return(int.MinValue);
         }
         else
         {
             return(segTrees[start.segId].GetCombine(start.segPos, end.segPos + 1));
         }
     }
 }
Beispiel #4
0
        public HLD(List <int[]> edges)
        {
            root = new HLDTreeNode()
            {
                id       = 0,
                parent   = null,
                children = new List <HLDTreeNode>(),
                value    = int.MinValue
            };
            segNodes.Add(new List <HLDTreeNode>()
            {
                root
            });
            nodes    = new HLDTreeNode[edges.Count + 1];
            nodes[0] = root;

            BuildTree(edges);
            HeavyLightDecomposition(root, 0);
            CreateSegTrees();
        }
Beispiel #5
0
        private void UpdateSize(HLDTreeNode node)
        {
            if (node.children.Count > 0)
            {
                foreach (var child in node.children)
                {
                    UpdateSize(child);
                }

                var t = 1;
                foreach (var child in node.children)
                {
                    t += child.size;
                }
                node.size = t;
            }
            else
            {
                node.size = 1;
            }
        }
Beispiel #6
0
        private void HeavyLightDecomposition(HLDTreeNode node, int index)
        {
            if (node.children.Count == 0)
            {
                return;
            }

            HLDTreeNode maxchild = null;
            var         max      = -1;

            foreach (var child in node.children)
            {
                if (child.size > max)
                {
                    maxchild = child;
                    max      = child.size;
                }
            }

            maxchild.segId  = index;
            maxchild.segPos = segNodes[index].Count;
            segNodes[index].Add(maxchild);
            HeavyLightDecomposition(maxchild, index);

            foreach (var child in node.children)
            {
                if (child != maxchild)
                {
                    var newIndex = segNodes.Count;
                    child.segId  = newIndex;
                    child.segPos = 0;
                    segNodes.Add(new List <HLDTreeNode>()
                    {
                        child
                    });
                    HeavyLightDecomposition(child, newIndex);
                }
            }
        }