def cut_nodes(graph):
    """
    Return the cut-nodes of the given graph.
    
    A cut node, or articulation point, is a node of a graph whose removal increases the number of
    connected components in the graph.
    
    @type  graph: graph, hypergraph
    @param graph: Graph.
        
    @rtype:  list
    @return: List of cut-nodes.
    """
    recursionlimit = getrecursionlimit()
    setrecursionlimit(max(len(graph.nodes())*2,recursionlimit))
    
    # Dispatch if we have a hypergraph
    if 'hypergraph' == graph.__class__.__name__:
        return _cut_hypernodes(graph)
        
    pre = {}    # Pre-ordering
    low = {}    # Lowest pre[] reachable from this node going down the spanning tree + one backedge
    reply = {}
    spanning_tree = {}
    pre[None] = 0
    
    # Create spanning trees, calculate pre[], low[]
    for each in graph:
        if (each not in pre):
            spanning_tree[each] = None
            _cut_dfs(graph, spanning_tree, pre, low, [], each)

    # Find cuts
    for each in graph:
        # If node is not a root
        if (spanning_tree[each] is not None):
            for other in graph[each]:
                # If there is no back-edge from descendent to a ancestral of each
                if (low[other] >= pre[each] and spanning_tree[other] == each):
                    reply[each] = 1
        # If node is a root
        else:
            children = 0
            for other in graph:
                if (spanning_tree[other] == each):
                    children = children + 1
            # root is cut-vertex iff it has two or more children
            if (children >= 2):
                reply[each] = 1

    setrecursionlimit(recursionlimit)
    return list(reply.keys())
dataset/ETHPy150Open nerdvegas/rez/src/rez/vendor/pygraph/algorithms/accessibility.py/cut_nodes/original