// For example, edges like (0, 1, 99), (1, 2, -3) => there's an edge between vertices 0 and 1 and 1 and 2. // Creating from edges also initializes depths and subtree sizes, because we have to DFS regardless. public static WeightedRootedTree <int> CreateFromEdges(int vertexCount, int rootID, int[,] edges) { var tree = new WeightedRootedTree <int>(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 just like // InitializeDepthsAndSubtreeSizes, so we might as well initialize depths & subtree sizes too. var verticesToVisit = new Stack <WeightedRootedTree <int> .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); } } tree.HasInitializedDepthsAndSubtreeSizes = true; return(tree); }
// E.g. if verticesChildEdges[1] = ((3, 99) (4, -3)), vertices w/ ID 3, 4 are the children of vertex w/ ID 1. // Creating from explicit children doesn't initialize depths or subtree sizes; do that separately if needed. public static WeightedRootedTree <int> CreateFromChildren( int vertexCount, int rootID, List <KeyValuePair <int, int> >[] verticesChildEdges) { var tree = new WeightedRootedTree <int>(vertexCount, rootID); for (int id = 0; id < vertexCount; ++id) { if (!verticesChildEdges[id]?.Any() ?? true) { continue; } var parent = tree.Vertices[id]; foreach (var childEdge in verticesChildEdges[id]) { tree.Vertices[childEdge.Key].SetParent(parent, childEdge.Value); } } return(tree); }
internal Vertex(WeightedRootedTree <T> tree, int ID) { _tree = tree; this.ID = ID; }