<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def minimal_spanning_tree(graph, root=None):
 """ Minimal spanning tree. @attention: Minimal spanning tree is meaningful only for weighted graphs. @type graph: graph @param graph: Graph. @type root: node @param root: Optional root node (will explore only root's connected component) @rtype: dictionary @return: Generated spanning tree. """

    visited = []            # List for marking visited and non-visited nodes
    spanning_tree = {}        # MInimal Spanning tree

    # Initialization
    if (root is not None):
        visited.append(root)
        nroot = root
        spanning_tree[root] = None
    else:
        nroot = 1
    
    # Algorithm loop
    while (nroot is not None):
        ledge = _lightest_edge(graph, visited)
        if (ledge == None):
            if (root is not None):
                break
            nroot = _first_unvisited(graph, visited)
            if (nroot is not None):
                spanning_tree[nroot] = None
            visited.append(nroot)
        else:
            spanning_tree[ledge[1]] = ledge[0]
            visited.append(ledge[1])

    return spanning_tree