
    \Mh                     4   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dS )zBridge-finding algorithms.    )chainN)not_implemented_for)bridgeshas_bridgeslocal_bridgesdirectedc              #     K   |                                  }|rt          j        |           n| }t          j        ||          }t	          t          j        |                    }|:|                    t          j        ||                    	                                }|
                                D ]9\  }}||f|vr.||f|vr(|r t          | |         |                   dk    r3||fV  :dS )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           [/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/networkx/algorithms/bridges.pyr   r      s      v ""J!(qA#AD111Fe)&1122KJJr21d;;<<AACC		  1q6$$!Q{)B)B c!A$q'llQ..Q$JJJ	     c                 f    	 t          t          | |                     dS # t          $ r Y dS 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   sN    hWQT"""### t    uus   " 
00r   weight)
edge_attrsTc              #     K   |dur@| j         D ]6\  }}t          | |                   t          | |                   z  s||fV  7dS t          j                            | |          | j         D ]\  }}t          | |                   t          | |                   z  sT||hfd}	 t          j        | |||          }|||fV  [# t          j        $ r ||t          d          fV  Y w xY wdS )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                 2    | vs|vr | ||          S d S N )nnbrdenodeswts      r   	hide_edgez local_bridges.<locals>.hide_edge   s-    #V*;*;!r!S!}},4r    )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      sY     V G 	 	DAq!IIAaD		) d


	 	 [))!V44G 	- 	-DAq!IIAaD		) -Q           
-21a9MMMDQ*$$$$( - - -Qe,,,,,,--	- 	-s   +C#C10C1r(   )TN)__doc__	itertoolsr   networkxr   networkx.utilsr   __all___dispatchabler   r   r   r)   r    r   <module>r>      s'                 . . . . . .
5
5
5 Z  C C C  ! CL Z  7 7 7  ! 7t \""Z  X&&&;- ;- ;- '& !  #";- ;- ;-r    