コード例 #1
0
        // 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);
        }
コード例 #2
0
        // 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);
        }
コード例 #3
0
 internal Vertex(WeightedRootedTree <T> tree, int ID)
 {
     _tree   = tree;
     this.ID = ID;
 }