Example:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_graph import *
        >>> G = nx.Graph()
        >>> G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5)])
        >>> G.adj[2][3]['lava'] = True
        >>> G.adj[3][4]['lava'] = True
        >>> def can_cross(G, edge, state):
        >>>     # can only cross lava once, then your lava protection wears off
        >>>     data = G.get_edge_data(*edge)
        >>>     lava = int(data.get('lava', False))
        >>>     if not lava or state == 0:
        >>>         return True, state + lava
        >>>     return False, lava
        >>> assert 5 not in dfs_conditional(G, 1, state=0, can_cross=can_cross)
        >>> G.adj[3][4]['lava'] = False
        >>> assert 5 in dfs_conditional(G, 1, state=0, can_cross=can_cross)

def dfs_conditional(G, source, state, can_cross):
    """
    Example:
        >>> # ENABLE_DOCTEST
        >>> from utool.util_graph import *
        >>> G = nx.Graph()
        >>> G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5)])
        >>> G.adj[2][3]['lava'] = True
        >>> G.adj[3][4]['lava'] = True
        >>> def can_cross(G, edge, state):
        >>>     # can only cross lava once, then your lava protection wears off
        >>>     data = G.get_edge_data(*edge)
        >>>     lava = int(data.get('lava', False))
        >>>     if not lava or state == 0:
        >>>         return True, state + lava
        >>>     return False, lava
        >>> assert 5 not in dfs_conditional(G, 1, state=0, can_cross=can_cross)
        >>> G.adj[3][4]['lava'] = False
        >>> assert 5 in dfs_conditional(G, 1, state=0, can_cross=can_cross)
    """
    # stack based version
    visited = {source}
    stack = [(source, iter(G[source]), state)]
    while stack:
        parent, children, state = stack[-1]
        try:
            child = next(children)
            if child not in visited:
                edge = (parent, child)
                flag, new_state = can_cross(G, edge, state)
                if flag:
                    yield child
                    visited.add(child)
                    stack.append((child, iter(G[child]), new_state))
        except StopIteration:
            stack.pop()