
    wg                        d Z ddlmZ ddlZddlmZ g dZ ed      ej                  dd              Z	 ed      ej                  dd              Z
 ed	       ed       ej                  d
      dd                     Zy)zBridge-finding algorithms.    )chainN)not_implemented_for)bridgeshas_bridgeslocal_bridgesdirectedc              #     K   | j                         }|rt        j                  |       n| }t        j                  ||      }t	        t        j                  |            }|3|j                  t        j                  ||            j                         }|j                         D ]0  \  }}||f|vs||f|vs|rt        | |   |         dkD  r+||f 2 yw)a@  Generate all bridges in a graph.

    A *bridge* in a graph is an edge whose removal causes the number of
    connected components of the graph to increase.  Equivalently, a bridge is an
    edge that does not belong to any cycle. Bridges are also known as cut-edges,
    isthmuses, or cut arcs.

    Parameters
    ----------
    G : undirected graph

    root : node (optional)
       A node in the graph `G`. If specified, only the bridges in the
       connected component containing this node will be returned.

    Yields
    ------
    e : edge
       An edge in the graph whose removal disconnects the graph (or
       causes the number of connected components to increase).

    Raises
    ------
    NodeNotFound
       If `root` is not in the graph `G`.

    NetworkXNotImplemented
        If `G` is a directed graph.

    Examples
    --------
    The barbell graph with parameter zero has a single bridge:

    >>> G = nx.barbell_graph(10, 0)
    >>> list(nx.bridges(G))
    [(9, 10)]

    Notes
    -----
    This is an implementation of the algorithm described in [1]_.  An edge is a
    bridge if and only if it is not contained in any chain. Chains are found
    using the :func:`networkx.chain_decomposition` function.

    The algorithm described in [1]_ requires a simple graph. If the provided
    graph is a multigraph, we convert it to a simple graph and verify that any
    bridges discovered by the chain decomposition algorithm are not multi-edges.

    Ignoring polylogarithmic factors, the worst-case time complexity is the
    same as the :func:`networkx.chain_decomposition` function,
    $O(m + n)$, where $n$ is the number of nodes in the graph and $m$ is
    the number of edges.

    References
    ----------
    .. [1] https://en.wikipedia.org/wiki/Bridge_%28graph_theory%29#Bridge-Finding_with_Chain_Decompositions
    rootN   )is_multigraphnxGraphchain_decompositionsetr   from_iterablesubgraphnode_connected_componentcopyedgeslen)Gr   
multigraphHchainschain_edgesuvs           `/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/bridges.pyr   r      s     v "J!qA##AD1Fe))&12KJJr221d;<AAC	 1q6$!Q{)Bc!A$q'lQ.Q$J	s   B0C3C: Cc                 P    	 t        t        | |             y# t        $ r Y yw xY w)a  Decide whether a graph has any bridges.

    A *bridge* in a graph is an edge whose removal causes the number of
    connected components of the graph to increase.

    Parameters
    ----------
    G : undirected graph

    root : node (optional)
       A node in the graph `G`. If specified, only the bridges in the
       connected component containing this node will be considered.

    Returns
    -------
    bool
       Whether the graph (or the connected component containing `root`)
       has any bridges.

    Raises
    ------
    NodeNotFound
       If `root` is not in the graph `G`.

    NetworkXNotImplemented
        If `G` is a directed graph.

    Examples
    --------
    The barbell graph with parameter zero has a single bridge::

        >>> G = nx.barbell_graph(10, 0)
        >>> nx.has_bridges(G)
        True

    On the other hand, the cycle graph has no bridges::

        >>> G = nx.cycle_graph(5)
        >>> nx.has_bridges(G)
        False

    Notes
    -----
    This implementation uses the :func:`networkx.bridges` function, so
    it shares its worst-case time complexity, $O(m + n)$, ignoring
    polylogarithmic factors, where $n$ is the number of nodes in the
    graph and $m$ is the number of edges.

    r
   TF)nextr   StopIteration)r   r   s     r   r   r   S   s0    hWQT"#   s    	%%r   weight)
edge_attrsc              #     K   |dur9| j                   D ])  \  }}t        | |         t        | |         z  r$||f + yt        j                  j	                  | |      | j                   D ]N  \  }}t        | |         t        | |         z  r$||hfd}	 t        j
                  | |||      }|||f P y# t        j                  $ r ||t        d      f Y ww xY ww)al  Iterate over local bridges of `G` optionally computing the span

    A *local bridge* is an edge whose endpoints have no common neighbors.
    That is, the edge is not part of a triangle in the graph.

    The *span* of a *local bridge* is the shortest path length between
    the endpoints if the local bridge is removed.

    Parameters
    ----------
    G : undirected graph

    with_span : bool
        If True, yield a 3-tuple `(u, v, span)`

    weight : function, string or None (default: None)
        If function, used to compute edge weights for the span.
        If string, the edge data attribute used in calculating span.
        If None, all edges have weight 1.

    Yields
    ------
    e : edge
        The local bridges as an edge 2-tuple of nodes `(u, v)` or
        as a 3-tuple `(u, v, span)` when `with_span is True`.

    Raises
    ------
    NetworkXNotImplemented
        If `G` is a directed graph or multigraph.

    Examples
    --------
    A cycle graph has every edge a local bridge with span N-1.

       >>> G = nx.cycle_graph(9)
       >>> (0, 8, 8) in set(nx.local_bridges(G))
       True
    Tc                 *    | vs|vr
 | ||      S y N )nnbrdenodeswts      r   	hide_edgez local_bridges.<locals>.hide_edge   s"    #V*;!!S!},    )r#   infN)r   r   r   weighted_weight_functionshortest_path_lengthNetworkXNoPathfloat)	r   	with_spanr#   r   r   r.   spanr,   r-   s	          @@r   r   r      s     V GG 	DAq!IAaD	)d
	 [[))!V4GG 	-DAq!IAaD	)Q 
-221a9MDQ*$	- (( -Qe,,-s5   4C)AC)
C) C =C) #C&#C)%C&&C)r'   )TN)__doc__	itertoolsr   networkxr   networkx.utilsr   __all___dispatchabler   r   r   r(   r/   r   <module>r>      s        .
5 Z C  !CL Z 7  !7t \"Z X&;- ' ! #;-r/   