
    Cii%                        d Z ddlmZmZ ddlZddlmZ g dZ ed           ed          ej	        d                                     Z
d	 Zej	        d
             Zej	        d             Zej	        d             Z ed           ed           ej	        d          dd                                    Z ed           ed           ej	        d          dd                                    ZdS )z;Functions for computing and verifying matchings in a graph.    )combinationsrepeatN)not_implemented_for)is_matchingis_maximal_matchingis_perfect_matchingmax_weight_matchingmin_weight_matchingmaximal_matching
multigraphdirectedc                     t                      }t                      }|                                 D ]?}|\  }}||vr4||vr0||k    r*|                    |           |                    |           @|S )a  Find a maximal matching in the graph.

    A matching is a subset of edges in which no node occurs more than once.
    A maximal matching cannot add more edges and still be a matching.

    Parameters
    ----------
    G : NetworkX graph
        Undirected graph

    Returns
    -------
    matching : set
        A maximal matching of the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)])
    >>> sorted(nx.maximal_matching(G))
    [(1, 2), (3, 5)]

    Notes
    -----
    The algorithm greedily selects a maximal matching M of the graph G
    (i.e. no superset of M exists). It runs in $O(|E|)$ time.
    )setedgesaddupdateGmatchingnodesedgeuvs         b/var/www/html/bet.cuttalo.com/ml/venv/lib/python3.11/site-packages/networkx/algorithms/matching.pyr   r      s{    < uuHEEE		   1E>>aunnaLLLLO    c                     t                      }|                                 D ]D}|\  }}||f|v s||v r||k    rt          j        d|           |                    |           E|S )a?  Converts matching dict format to matching set format

    Converts a dictionary representing a matching (as returned by
    :func:`max_weight_matching`) to a set representing a matching (as
    returned by :func:`maximal_matching`).

    In the definition of maximal matching adopted by NetworkX,
    self-loops are not allowed, so the provided dictionary is expected
    to never have any mapping from a key to itself. However, the
    dictionary is expected to have mirrored key/value pairs, for
    example, key ``u`` with value ``v`` and key ``v`` with value ``u``.

    z%Selfloops cannot appear in matchings )r   itemsnxNetworkXErrorr   )r   r   r   r   r   s        r   matching_dict_to_setr    <   s     EEE    1q6U??demm66"#Q4#Q#QRRR		$Lr   c                    t          |t                    rt          |          }t                      }|D ]}t	          |          dk    rt          j        d|           |\  }}|| vs|| vrt          j        d| d          ||k    r dS |                     ||          s dS ||v s||v r dS |                    |           dS )a  Return True if ``matching`` is a valid matching of ``G``

    A *matching* in a graph is a set of edges in which no two distinct
    edges share a common endpoint. Each node is incident to at most one
    edge in the matching. The edges are said to be independent.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid matching
        in the graph.

    Raises
    ------
    NetworkXError
        If the proposed matching has an edge to a node not in G.
        Or if the matching is not a collection of 2-tuple edges.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5)])
    >>> nx.is_maximal_matching(G, {1: 3, 2: 4})  # using dict to represent matching
    True

    >>> nx.is_matching(G, {(1, 3), (2, 4)})  # using set to represent matching
    True

       matching has non-2-tuple edge matching contains edge  with node not in GFT	
isinstancedictr    r   lenr   r   has_edger   r   s         r   r   r   U   s    R (D!! 2'11EEE  t99>>"#JD#J#JKKK1A::!"#VT#V#V#VWWW6655zz!Q 	55::e55T4r   c                 R   t          |t                    rt          |          }t                      }t                      }|D ]}t	          |          dk    rt          j        d|           |\  }}|| vs|| vrt          j        d| d          ||k    r dS |                     ||          s dS ||v s||v r dS |                    |           |	                    |           |	                    ||f           | j
        D ]\  }}||f|vr||vr||vr	||k    r dS dS )ag  Return True if ``matching`` is a maximal matching of ``G``

    A *maximal matching* in a graph is a matching in which adding any
    edge would cause the set to no longer be a valid matching.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid maximal
        matching in the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (3, 4), (3, 5)])
    >>> nx.is_maximal_matching(G, {(1, 2), (3, 4)})
    True

    r"   r#   r$   r%   FT)r'   r(   r    r   r)   r   r   r*   r   r   r   )r   r   r   r   r   r   r   s          r   r   r      so   > (D!! 2'11EEEEEE  t99>>"#JD#J#JKKK1A::!"#VT#V#V#VWWW6655zz!Q 	55::e55T		$		1a&   1q6~~!5..Q!VVuu4r   c                    t          |t                    rt          |          }t                      }|D ]}t	          |          dk    rt          j        d|           |\  }}|| vs|| vrt          j        d| d          ||k    r dS |                     ||          s dS ||v s||v r dS |                    |           t	          |          t	          |           k    S )a  Return True if ``matching`` is a perfect matching for ``G``

    A *perfect matching* in a graph is a matching in which exactly one edge
    is incident upon each vertex.

    Parameters
    ----------
    G : NetworkX graph

    matching : dict or set
        A dictionary or set representing a matching. If a dictionary, it
        must have ``matching[u] == v`` and ``matching[v] == u`` for each
        edge ``(u, v)`` in the matching. If a set, it must have elements
        of the form ``(u, v)``, where ``(u, v)`` is an edge in the
        matching.

    Returns
    -------
    bool
        Whether the given set or dictionary represents a valid perfect
        matching in the graph.

    Examples
    --------
    >>> G = nx.Graph([(1, 2), (1, 3), (2, 3), (2, 4), (3, 5), (4, 5), (4, 6)])
    >>> my_match = {1: 2, 3: 5, 4: 6}
    >>> nx.is_perfect_matching(G, my_match)
    True

    r"   r#   r$   r%   Fr&   r   s         r   r   r      s   @ (D!! 2'11EEE  t99>>"#JD#J#JKKK1A::!"#VT#V#V#VWWW6655zz!Q 	55::e55Tu::Qr   weight)
edge_attrsc                 R   t          | j                  dk    rt          | d|          S |                     |d          }dt          d |D                       z   t	          j                    }fd|D             }|                    ||           t          |d|          S )	a  Compute a minimum-weight maximum-cardinality matching of `G`.

    The minimum-weight maximum-cardinality matching is the matching
    that has the minimum weight among all maximum-cardinality matchings.

    Use the maximum-weight algorithm with edge weights subtracted
    from the maximum weight of all edges.

    A matching is a subset of edges in which no node occurs more than once.
    The weight of a matching is the sum of the weights of its edges.
    A maximal matching cannot add more edges and still be a matching.
    The cardinality of a matching is the number of matched edges.

    This method replaces the edge weights with 1 plus the maximum edge weight
    minus the original edge weight.

    new_weight = (max_weight + 1) - edge_weight

    then runs :func:`max_weight_matching` with the new weights.
    The max weight matching with these new weights corresponds
    to the min weight matching using the original weights.
    Adding 1 to the max edge weight keeps all edge weights positive
    and as integers if they started as integers.

    Read the documentation of `max_weight_matching` for more information.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    weight: string, optional (default='weight')
       Edge data key corresponding to the edge weight.
       If key not found, uses 1 as weight.

    Returns
    -------
    matching : set
        A minimal weight matching of the graph.

    See Also
    --------
    max_weight_matching
    r   T)maxcardinalityr-      )datadefaultc              3   "   K   | ]
\  }}}|V  d S N ).0_ws      r   	<genexpr>z&min_weight_matching.<locals>.<genexpr>7  s(      22wq!Q222222r   c              3   0   K   | ]\  }}}|||z
  fV  d S r5   r6   )r7   r   r   r9   
max_weights       r   r:   z&min_weight_matching.<locals>.<genexpr>9  s4      ;;1aaJN#;;;;;;r   r-   )r)   r   r	   maxr   Graphadd_weighted_edges_from)r   r-   G_edgesInvGr   r<   s        @r   r
   r
     s    ` 17||q"1T&IIIIgg61g--GS22'222222J8::D;;;;7;;;E  v 666tDHHHHr   Fc                 J    !"#$%&'()*  G d d           G fdd          t                     $$st                      S d}d}                     d          D ]c\  }}}|                    d          }||k    r||k    r|}|o6t	          t          |                                        d	          d         d
v }di (i &i 't          t          $$                    %t          t          $t          d                              "t          t          $$                     i t          t          $t          |                              #i !i g ) #fd* %&'()f	d %&'(fd}	  !"%&'()*fd}
 !"%&'(fd} "(fd %&'(fd} !"#$(fd}	 &
                                 '
                                 
                                 !D ]	}d|_        

                                 g )dd<   $D ].}|(vr(&                    %|                    |dd           /d}	 )r|s)                                }&%|                  dk    sJ                      |          D ]m}||k    r
%|         }%|         }||k    r!||fvr  *||          }|dk    rdx||f<   ||f<   ||fv r&                    |           |d|           p&                    |          dk    r. |	||          }|ur |
|||            |||           d} n&                    |          &|         dk    sJ d&|<   ||f'|<   &                    |          dk    r-                    |          | *|          k     r||f|<   -&                    |          +                    |          | *|          k     r||f|<   o)r||rnd}dx}x}}s#d}t          #                                          }                                 D ]U}&                    %|                   8                    |          # *|          }|dk    s||k     r|}d}|         }V"D ]s}"|         i&                    |          dk    rP                    |          ; *|          }|r|dz  dk    sJ |dz  }n|dz  }|dk    s||k     r|}d}|         }t!D ]A}"|         7&                    |          dk    r|dk    s!|         |k     r!|         }d}|}B|dk    r5sJ d}t#          dt          #                                                    }$D ]a}&                    %|                   dk    r#|xx         |z  cc<   2&                    %|                   dk    r#|xx         |z  cc<   b!D ]]}"|         S&                    |          dk    r!|xx         |z  cc<   4&                    |          dk    r!|xx         |z  cc<   ^|dk    rn|dk    r=|\  }}&%|                  dk    sJ dx||f<   ||f<   )                    |           nU|dk    r=|\  }}dx||f<   ||f<   &%|                  dk    sJ )                    |           n|dk    r ||d           (D ]}((|                  |k    sJ |sndt          !                                          D ]@}|!vr"|         1&                    |          dk    r!|         dk    r ||d           A|r
 |             t)          (          S )a  Compute a maximum-weighted matching of G.

    A matching is a subset of edges in which no node occurs more than once.
    The weight of a matching is the sum of the weights of its edges.
    A maximal matching cannot add more edges and still be a matching.
    The cardinality of a matching is the number of matched edges.

    Parameters
    ----------
    G : NetworkX graph
      Undirected graph

    maxcardinality: bool, optional (default=False)
       If maxcardinality is True, compute the maximum-cardinality matching
       with maximum weight among all maximum-cardinality matchings.

    weight: string, optional (default='weight')
       Edge data key corresponding to the edge weight.
       If key not found, uses 1 as weight.


    Returns
    -------
    matching : set
        A maximal matching of the graph.

     Examples
    --------
    >>> G = nx.Graph()
    >>> edges = [(1, 2, 6), (1, 3, 2), (2, 3, 1), (2, 4, 7), (3, 5, 9), (4, 5, 3)]
    >>> G.add_weighted_edges_from(edges)
    >>> sorted(nx.max_weight_matching(G))
    [(2, 4), (5, 3)]

    Notes
    -----
    If G has edges with weight attributes the edge data are used as
    weight values else the weights are assumed to be 1.

    This function takes time O(number_of_nodes ** 3).

    If all edge weights are integers, the algorithm uses only integer
    computations.  If floating point weights are used, the algorithm
    could return a slightly suboptimal matching due to numeric
    precision errors.

    This method is based on the "blossom" method for finding augmenting
    paths and the "primal-dual" method for finding a matching of maximum
    weight, both methods invented by Jack Edmonds [1]_.

    Bipartite graphs can also be matched using the functions present in
    :mod:`networkx.algorithms.bipartite.matching`.

    References
    ----------
    .. [1] "Efficient Algorithms for Finding Maximum Matching in Graphs",
       Zvi Galil, ACM Computing Surveys, 1986.
    c                       e Zd ZdZdS )#max_weight_matching.<locals>.NoNodez-Dummy value which is different from any node.N)__name__
__module____qualname____doc__r6   r   r   NoNoderE     s        ;;;;r   rJ   c                   &    e Zd ZdZg dZ fdZdS )$max_weight_matching.<locals>.Blossomz7Representation of a non-trivial blossom or sub-blossom.)childsr   mybestedgesc              3      K   g | j         }|rG|                                }t          |          r|                    |j                    n|V  |Ed S d S r5   )rM   popr'   extend)selfstacktBlossoms      r   leavesz+max_weight_matching.<locals>.Blossom.leaves  sw      "dkNE IIKKa)) LL****GGG      r   N)rF   rG   rH   rI   	__slots__rV   )rU   s   r   rU   rL     s?        EE666		 	 	 	 	 	 	r   rU   r   Tr2   r1   ')intlongNc                 r    |          |         z   d|          |                              d          z  z
  S )Nr"   r1   )get)r   r9   r   dualvarr-   s     r   slackz"max_weight_matching.<locals>.slack  s6    qzGAJ&QqT!W[[-C-C)CCCr   c                   	 	|          }
                     |           
                     |          J |x
| <   
|<   ||| fx| <   |<   n
d x| <   |<   d x| <   |<   |dk    rPt          |          r)                    |                                           d S                     |           d S |dk    r|         } |         d|           d S d S )Nr1   r"   )r]   r'   rQ   rV   append)r9   rT   r   bbaserU   assignLabelbestedgeblossombase	inblossomlabel	labeledgematequeues        r   rd   z(max_weight_matching.<locals>.assignLabel  s   aLyy||#		!(<(<(<a58=+,a&0IaL9Q<<*..IaL9Q<$((hqk66!W%%  QXXZZ(((((Q!VV q>DKT
At,,,,, Vr   c                    g }}| ur|          }|         dz  r	|         }n|         dk    sJ |                     |           d|<   	|         |         
vsJ } nR	|         d         
|                  k    sJ 	|         d         } |          }|         dk    sJ 	|         d         } |ur|| }} | u|D ]}d|<   |S )N   r1      r   r"   )ra   )r   r9   pathrc   rb   rJ   rf   rg   rh   ri   rj   s        r   scanBlossomz(max_weight_matching.<locals>.scanBlossom  s   voo!AQx!| "1~8q====KKNNNE!H|#"1~T1111 |A${1~*>>>>>aLOaLQx1}}}}aLO!1/ voo2  	 	AE!HHr   c                    |          }|         |         }             }| |<   d |<   ||<   g x|_         }||fgx|_        }|k    r|<   |                               |                                                 dk    s,         dk    r         d                           k    sJ          d         }|         |k    |                    |           |                                 |                                 ||k    r||<   |                    |           |                    |         d         |         d         f           |         dk    s,|         dk    r|         d         |                  k    sJ |         d         }|         }||k    |         dk    sJ d|<   |         |<   d|<   |                                D ].}|                  dk    r                    |           ||<   /i }|D ]Ҋt                    r7j        j        }	d _        nBfd                                D             }	n!fd                              D             }	|	D ]`}
|
\  }}|         |k    r||}}|         }||k    r;                    |          dk    r"||vs ||           ||          k     r|
||<   ad <   t          |
                                          |_        d }d |<   |j        D ]}
 |
 }|||k     r|
}|}||<   d S )Nr"   r1   r   c                 T    g | ]$}                     |          D ]}||k    ||f%S r6   )	neighbors)r7   r   r9   r   s      r   
<listcomp>z;max_weight_matching.<locals>.addBlossom.<locals>.<listcomp>  sE       #$Q[[^^ 89qTUvvAvvvvr   c                 $    g | ]}|k    |fS r6   r6   )r7   r9   bvs     r   rt   z;max_weight_matching.<locals>.addBlossom.<locals>.<listcomp>  s"    FFFabAgg2q'gggr   )rM   r   ra   reverserV   r'   rN   rs   r]   listvalues)rc   r   r9   bbbwrb   ro   edgs
bestedgetonblistkijbj
mybestedgekslackmybestslackrv   rU   r   re   rf   blossomdualblossomparentrg   rh   ri   rj   rk   r_   s                    @r   
addBlossomz'max_weight_matching.<locals>.addBlossom?  s   t_q\q\GIIAab4a&!$Bhh !M"KKOOOKK	"&&&9>>b	Q9R=#3tKO7L#L#L#L#L "a A1B Bhh 	BBhh !M"KKOOOKK2q)9R=+;<===9>>b	Q9R=#3tKO7L#L#L#L#L "a A1B Bhh RyA~~~~a }	!A 	 	AYq\"a'' QIaLL
 	  	 B"g&& G>-^F%)BNN   (*		  FF GFFF1;;r??FFF 
' 
'AQ<1$$aqAq\!GG		"**J..55A;;
SUAW3W3W%&JrNHRLLZ..0011
 	% 	%AUAYF!Vk%9%9
$ r   c                     	
fd} || |          g}|rE|d         }|D ]"}|                      |||                      n|                                 |Cd S d S )Nc              3     K   | j         D ]L}d |<   t          |          r0|r|         dk    r|V  *|                                D ]}||<   G||<   M|s2                    |           dk    r|          d                  }| j                             |          }|dz  r|t          | j                   z  }d}nd}|          \  }}|dk    r|dk    r| j        |         \  }}	n| j        |dz
           \  }	}d |<   d |	<    |d|           dx||	f<   |	|f<   ||z  }|dk    r| j        |         \  }}n| j        |dz
           \  }}dx||f<   ||f<   ||z  }|dk    | j         |         }
dx|<   |
<   ||fx|<   |
<   d |
<   ||z  }| j         |         |k    r| j         |         }                    |          dk    r||z  }=t          |          r/|                                D ]}                    |          r nn|}                    |          rK|         dk    sJ |         |k    sJ d |<   d |                  <    |d|         d                    ||z  }| j         |         |k                        | d                                | d                                | d            | = | = | = d S )Nr   r"   r1   T)rM   r'   rV   r]   indexr)   r   rP   )rb   endstagesr   
entrychildr   jstepr9   pqr{   rv   rU   	allowedgerd   re   rf   r   r   rg   rh   ri   rj   s               r   _recursez<max_weight_matching.<locals>.expandBlossom.<locals>._recurse  s     X 
% 
%#'a a)) % -KNa$7$7!" - -A+,IaLL- $%IaLL  E%))A,,!"3"3 'y|A7
HNN:..q5 QX&AEE E |11ffzz wqz11 wq1u~1#E!H#E!HK1a(((<@@Iq!f%	1a&(9JAzz wqz11 wq1u~1<@@Iq!f%	1a&(9JA% 1ff* Xa['((a59011v5	!y}#U
hqkZ// !Byy}})) U
 !"g.. !# & &A$yy|| & %&  yy|| ;$Qx1}}}}(|r1111#'a7;d;r?34#Aq)A,q/:::JA1 hqkZ//4 IIaMM!T"""LLD!!!a AAr   r   ra   rP   )rb   r   r   rS   topr   rU   r   rd   re   rf   r   r   rg   rh   ri   rj   s         r   expandBlossomz*max_weight_matching.<locals>.expandBlossom  s    [	 [	 [	 [	 [	 [	 [	 [	 [	 [	 [	 [	 [	 [	 [	D !X&&' 	)C  XXa22333		  	 	 	 	 	r   c                     	fd} || |          g}|r>|d         }|D ]}|                      ||             n|                                 |<d S d S )Nc              3     K   |}
|         | k    r
|         }
|         | k    t          |          r||fV  | j                            |          x}}|dz  r|t          | j                  z  }d}nd}|dk    r||z  }| j        |         }|dk    r| j        |         \  }}n| j        |dz
           \  }}t          |          r||fV  ||z  }| j        |         }t          |          r||fV  ||<   ||<   |dk    | j        |d          | j        d |         z   | _        | j        |d          | j        d |         z   | _        	| j        d                  	| <   	|          |k    sJ d S )Nr1   r   r   )r'   rM   r   r)   r   )rb   r   rT   r   r   r   r9   xrU   rf   r   rj   s           r   r   z=max_weight_matching.<locals>.augmentBlossom.<locals>._recurse  s      A"a''!!$  "a'' !W%% !fHNN1%%%A1u S]]" q&&U
HQKA::71:DAqq71q5>DAqa)) !a&LLLU
HQKa)) !a&LLLQQ# q&&& x|ahrrl2AHgabbkAGBQBK/AG(!5KNq>Q&&&&&&r   r   r   )
rb   r   r   rS   r   argsrU   rf   r   rj   s
         r   augmentBlossomz+max_weight_matching.<locals>.augmentBlossom  s    )	' )	' )	' )	' )	' )	' )	' )	'` !Q  	)C  XXt_---		  	 	 	 	 	r   c                    | |f|| ffD ]\  }}	 
|         }|         dk    sJ |         
	|         vs |         d         	|                  k    sJ t          |          r ||           ||<   |         n_|         d         }
|         }|         dk    sJ |         \  }}	|         |k    sJ t          |          r ||           ||<   ьd S )Nr1   r   r"   )r'   )r   r9   r   r   bsrT   btrU   r   rf   rg   rh   ri   rj   s          r   augmentMatchingz,max_weight_matching.<locals>.augmentMatchingS  sD   VaV$ 	 	DAqq\RyA~~~~!"-+b/2M2MbM!$[_(===== b'** *"N2q)))QR=(bM!$q\RyA~~~~ }1"2!++++b'** *"N2q)))Q3 %	 	r   c                  0   r1t          dt                                                               } nd} t                                                    | z   dk    sJ t                    dk    s't                                                    dk    sJ                     d          D ]k\  }}}|                    d          }||k    r$|         |         z   d|z  z
  }|g}|g}|d                  /|                    |d                             |d                  /|d                  /|                    |d                             |d                  /|                                 |                                 t          ||          D ]\  }}	||	k    r n|d|         z  z  }|dk    sJ                     |          |k    s                    |          |k    r"|         |k    r|         |k    sJ |dk    sJ mD ]}
|
v s|
         | z   dk    sJ D ][}|         dk    rMt          |j                  dz  dk    sJ |j        dd d         D ]\  }}|         |k    r|         |k    sJ  \d S )Nr   TrX   r1   r"   r   )	r>   minry   r)   r   r]   ra   rw   zip)vdualoffsetr   r   dwtr   	iblossoms	jblossomsbir   r   rb   r   r   r   r^   gnodesrj   r0   r-   s               r   verifyOptimumz*max_weight_matching.<locals>.verifyOptimumt  s    	 a#gnn&6&6"7"7!788KKK7>>##$${2a7777;1$$K,>,>,@,@(A(AQ(F(F(F(F wwDw)) 	 	GAq!vq!!BAvv
WQZ'!b&0AII	".:  y}!=>>>  	".:	".:  y}!=>>>  	".:i33 ) )B88EQR((6666xx{{a488A;;!#3#3Aw!||Q1Avvvv 	@ 	@AII'!*{":a"?"?"?"? 	9 	9A1~!!17||a'1,,,,GADqDM 9 9DAq7a<<DGqLLLLL		9 	9r   r"   r   g       @   rm   F)rx   r   r   r]   strtypesplitr(   r   r   clearrN   rP   rs   r   ry   r   r>   ra   keysr    )+r   r0   r-   	maxweight
allintegerr   r   r   r   rp   r   r   r   r   rb   r   	augmentedr9   rv   r{   r   rc   	deltatypedelta	deltaedgedeltablossomrU   rJ   r   rd   r   re   rf   r   r   r^   r   rg   rh   ri   rj   rk   r_   s+   ```                       @@@@@@@@@@@@@@@@@r   r	   r	   >  sW   X< < < < < < < <         8 !WWF uu IJ777%% U U1aUU6166b9nnITSb]]%8%8%=%=a%@O%S


 D E I S(())I
 VVD\\2233M s66**++K H 3vvi001122G
 K
 I ED D D D D D D
- - - - - - - - - - - - -2                   J\! \! \! \! \! \! \! \! \! \! \! \! \! \! \! \!~o o o o o o o o o o o o o o oh= = = = = = = =B          B)9 )9 )9 )9 )9 )9 )9 )9 )9 )9 )9 )9ZU' 	 	 	! 	!A AMM 	 aaa  	( 	(A599Yq\#:#:#BAq$''' 	h	3  :1	 :1IIKKYq\*a//// Q 41 41AAvv "1B"1BRxx 1vY..!&q!!Q;;DHHIq!f-	1a&0A1v** 99R==0 (K1a0000"YYr]]a// $/;q!#4#4D#611 !+
4A 6 6 6 6 !01 5 5 5,-	 %"YYq\\1
 $)9>>>>'(E!H,-q6IaL2!++ $<<++3vxPR|@T7T7T,-q6HRL1- $<<??2fuuhqk?R6R6R+,a&HQKu  :1	 :1x   I/33E3I " .	GNN,,-- WWYY 0 099Yq\**2x||A7Rx{+A B!e)) !$%	$,QK	 # 0 0!!$,		!)) Q3"UHQK0F! ) &
q0000"aK"SL B!e)) !$%	$,QK	 ! % %!!$,		!))"bKNU,B,B'NE !I#$LB &%%%	As7>>#3#34455  ( (99Yq\**a//AJJJ%'JJJJYYy|,,11AJJJ%'JJJ  0 0 #+yy||q((#A%/1**#A%/ A~~a"AYq\*a////8<<	1a&!Iq!f$5Qa"A8<<	1a&!Iq!f$5Yq\*a////QalE222Qh	3Z  	& 	&AQ=A%%%%%  	 k&&(()) 	' 	'A##Q'EIIaLLA,=,=+a.TUBUBUa&&&kU'p  %%%r   r=   )Fr-   )rI   	itertoolsr   r   networkxr   networkx.utilsr   __all___dispatchabler   r    r   r   r   r
   r	   r6   r   r   <module>r      s   A A * * * * * * * *     . . . . . .   \""Z  $ $  !  #"$N  2 9 9 9x : : :z 0  0  0 f \""Z  X&&&4I 4I 4I '& !  #"4In \""Z  X&&&{& {& {& '& !  #"{& {& {&r   