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)); }
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); }
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)); } } }
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(); }
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; } }
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); } } }