
    wg                        d Z ddlm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y)z;Functions for computing and verifying matchings in a graph.    )Counter)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               }| j                         D ]9  }|\  }}||vs||vs||k7  s|j                  |       |j                  |       ; |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         a/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/networkx/algorithms/matching.pyr   r      sd    < uHEE	  1E>aunaLLLL O    c                     t               }| j                         D ]@  }|\  }}||f|v s||v r||k(  rt        j                  d|       |j	                  |       B |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!   =   sp     EE  1q6U?dem6""%J4&#QRR		$ Lr   c                 `   t        |t              rt        |      }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |        y)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   V   s    R (D!'1EE t9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT r   c                    t        |t              rt        |      }t               }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |       |j                  |       |j                  ||f        | j                  D ]  \  }}||f|vs||vs||vs||k7  s y y)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      s   > (D!'1EEEE t9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT		$		1a&$  1q6~!5.Q!V	
 r   c                    t        |t              rt        |      }t               }|D ]  }t	        |      dk7  rt        j                  d|       |\  }}|| vs|| vrt        j                  d| d      ||k(  r y| j                  ||      s y||v s||v r y|j                  |        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!'1EE t9>""%CD6#JKK1A:!""%<TFBU#VWW6zz!Q:eT u:Qr   weight)
edge_attrsc                     t        | j                        dk(  rt        | d|      S | j                  |d      }dt        d |D              z   t	        j
                         }fd|D        }|j                  ||       t        |d|      S )	a  Computing a minimum-weight maximal matching of G.

    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.

    You might worry that adding 1 to each weight would make the algorithm
    favor matchings with more edges. But we use the parameter
    `maxcardinality=True` in `max_weight_matching` to ensure that the
    number of edges in the competing matchings are the same and thus
    the optimum does not change due to changes in the number of edges.

    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   | ]
  \  }}}|  y wN ).0_ws      r   	<genexpr>z&min_weight_matching.<locals>.<genexpr>;  s     2wq!Q2s   c              3   6   K   | ]  \  }}}|||z
  f  y wr6   r7   )r8   r   r   r:   
max_weights       r   r;   z&min_weight_matching.<locals>.<genexpr>=  s"     ;1aaJN#;s   r.   )r*   r   r
   maxr   Graphadd_weighted_edges_from)r   r.   G_edgesInvGr   r=   s        @r   r   r     s    f 177|q"1T&IIgg61g-GS2'222J88:D;7;E  v 6tDHHr   c                     !"#$%&'()*  G d d       G fdd      t               $$s
t               S d}d} j                  d      D ]P  \  }}}|j                  d      }||k7  r||kD  r|}|xr( t	        t        |            j                  d	      d   d
v }R i (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}	 &j                          'j                          j                          !D ]	  }d|_         j                          g )dd $D ]&  }|(vs&j                  %|          |dd       ( d}	 )rk|sh)j                         }&%|      dk(  sJ  j                  |      D ]0  }||k(  r
%|   }%|   }||k(  r||fvr *||      }|dk  rdx||f<   ||f<   ||fv r~&j                  |       |d|       ^&j                  |      dk(  r% |	||      }|ur |
|||        |||       d} n&j                  |      &|   dk(  sJ d&|<   ||f'|<   &j                  |      dk(  r%j                  |       *|    k  s||f|<   &j                  |      j                  |       *|    k  s*||f|<   3 )r|sh|rnqd}dx}x}}sd}t        #j                               } j!                         D ]E  }&j                  %|         j                  |      * *|    }|dk(  s||k  s=|}d}|   }G "D ]b  }"|   	&j                  |      dk(  sj                  |      0 *|    }|r|dz  dk(  sJ |dz  }n|dz  }|dk(  s||k  sZ|}d}|   }d !D ]4  }"|   	&j                  |      dk(  s|dk(  s	!|   |k  s,!|   }d}|}6 |dk(  r)sJ d}t#        dt        #j                                     }$D ]L  }&j                  %|         dk(  r#|xx   |z  cc<   (&j                  %|         dk(  s@#|xx   |z  cc<   N !D ]L  }"|   	&j                  |      dk(  r!|xx   |z  cc<   +&j                  |      dk(  s@!|xx   |z  cc<   N |dk(  rn~|dk(  r2|\  }}&%|      dk(  sJ dx||f<   ||f<   )j%                  |       nE|dk(  r2|\  }}dx||f<   ||f<   &%|      dk(  sJ )j%                  |       n|dk(  r	 ||d       (D ]  }((|      |k(  rJ  |snRt        !j'                               D ]4  }|!vr"|   &j                  |      dk(  s#!|   dk(  s, ||d       6 |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y)#max_weight_matching.<locals>.NoNodez-Dummy value which is different from any node.N)__name__
__module____qualname____doc__r7   r   r   NoNoderF     s    ;r   rK   c                   $    e Zd ZdZg dZ fdZy)$max_weight_matching.<locals>.Blossomz7Representation of a non-trivial blossom or sub-blossom.)childsr   mybestedgesc              3      K   g | j                   }|r@|j                         }t        |      r|j                  |j                          n| |r?y y wr6   )rN   popr(   extend)selfstacktBlossoms      r   leavesz+max_weight_matching.<locals>.Blossom.leaves  sF     "dkkNEIIKa)LL*G s   AAAN)rG   rH   rI   rJ   	__slots__rW   )rV   s   r   rV   rM     s    E6		r   rV   r   Tr3   r2   ')intlongNc                 R    |    |   z   d|    |   j                  d      z  z
  S )Nr#   r2   )get)r   r:   r   dualvarr.   s     r   slackz"max_weight_matching.<locals>.slack   s3    qzGAJ&QqT!W[[-C)CCCr   c                 h  	 	|    }
j                  |       
j                  |      J |x
| <   
|<   ||| fx| <   |<   n
d x| <   |<   d x| <   |<   |dk(  r>t        |      r j                  |j                                y j	                  |       y |dk(  r|   } |   d|       y y )Nr2   r#   )r^   r(   rR   rW   append)r:   rU   r   bbaserV   assignLabelbestedgeblossombase	inblossomlabel	labeledgematequeues        r   re   z(max_weight_matching.<locals>.assignLabel  s    aLyy|#		!(<<<a58=+,a&0IaL9Q<*..IaL9Q<$((hqk6!W%QXXZ(Q!V q>DT
At, r   c                 6   g }}| ur|    }|   dz  r|   }np|   dk(  sJ |j                  |       d|<   	|   |   
vsJ } n2	|   d   
|      k(  sJ 	|   d   } |    }|   dk(  sJ 	|   d   } |ur|| }} | ur|D ]  }d|<   	 |S )N   r2      r   r#   )rb   )r   r:   pathrd   rc   rK   rg   rh   ri   rj   rk   s        r   scanBlossomz(max_weight_matching.<locals>.scanBlossom  s   vo!AQx!|"1~8q= =KKNE!H|#"1~T111 |A${1~*>>>>aLOaLQx1}$}aLO!1/ vo2  	AE!H	 r   c                    |    }|   }|   }        }| |<   d |<   ||<   g x|_         }||fgx|_        }||k7  r`||<   |j                  |       |j                  |          |   dk(  s|   dk(  r|   d   |      k(  sJ |   d   }|   }||k7  r`|j                  |       |j                          |j                          ||k7  rk||<   |j                  |       |j                  |   d   |   d   f       |   dk(  s|   dk(  r|   d   |      k(  sJ |   d   }|   }||k7  rk|   dk(  sJ d|<   |   |<   d|<   |j	                         D ]#  }|      dk(  rj                  |       ||<   % i }	|D ]  }t        |      r^|j                  |j                  }
d |_        nd|j	                         D cg c]"  }j                  |      D ]  }||k7  s	||f $ }
}}n&j                  |      D cg c]  }||k7  s	||f }
}|
D ]O  }|\  }}|   |k(  r||}}|   }||k7  sj                  |      dk(  s4||	vs ||       |	|    k  sK||	|<   Q d |<    t        |	j                               |_        d }d |<   |j                  D ]  } | }||k  s|}|} ||<   y c c}}w c c}w )Nr#   r2   r   )rN   r   rb   reverserW   r(   rO   	neighborsr^   listvalues)rd   r   r:   bbbvbwrc   rp   edgs
bestedgetonblistkijbj
mybestedgekslackmybestslackrV   r   rf   rg   blossomdualblossomparentrh   ri   rj   rk   rl   r`   s                     r   
addBlossomz'max_weight_matching.<locals>.addBlossomC  s   t_q\q\IAab4a&!$Bh !M"KKOKK	"&9>b	Q9R=#3tKO7L#L  "a A1B Bh 	BBh !M"KKOKK2q)9R=+;<=9>b	Q9R=#3tKO7L#L  "a A1B Bh RyA~~a }	!A 	AYq\"a' QIaL	 
 	 B"g&>>-^^F%)BN
 )+		#$Q[[^89qTUvAF  ,-;;r?FabAg2q'FF 
'AQ<1$aqAq\!G		"*J.5A;
SUAW3W%&JrN
'  HRL7	 8 Z..01
 	%AAYF!Vk%9
$		%
 !7 Gs   K9K
K#Kc                     	
fd} || |      g}|r9|d   }|D ]  }|j                   |||              n |j                          |r8y y )Nc              3   8  K   | j                   D ]B  }d |<   t        |      r*|r|   dk(  r| #|j                         D ]  }||<   	 >||<   D |sj                  |       dk(  r|    d      }| j                   j	                  |      }|dz  r|t        | j                         z  }d}nd}|    \  }}|dk7  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k7  r| j                   |   }
dx|<   |
<   ||fx|<   |
<   d |
<   ||z  }| j                   |   |k7  r| j                   |   }j                  |      dk(  r||z  };t        |      r)|j                         D ]  }j                  |      s n n|}j                  |      r4|   dk(  sJ |   |k(  sJ d |<   d |      <    |d|   d          ||z  }| j                   |   |k7  rj                  | d        j                  | d        j                  | d        | = | = | = y w)Nr   r#   r2   T)rN   r(   rW   r^   indexr*   r   rQ   )rc   endstagesr   
entrychildr   jstepr:   pqry   rx   rV   	allowedgere   rf   rg   r   r   rh   ri   rj   rk   s               r   _recursez<max_weight_matching.<locals>.expandBlossom.<locals>._recurse  s    XX 
%#'a a)KNa$7!" -A+,IaL- $%IaL
% %))A,!"3 'y|A7
HHNN:.q5QXX&AE E |11fz wwqz1 wwq1u~1#E!H#E!H1a(<@@Iq!f%	1a&(9JAz wwqz1 wwq1u~1<@@Iq!f%	1a&(9JA% 1f* XXa['((a59011v5	!y}#U
hhqkZ/ !Byy}) U
 !"g.!# &A$yy| %&  yy|$Qx1},}(|r111#'a7;d;r?34#Aq)A,q/:JA1 hhqkZ/4 IIaMM!T"LLD!a AAs   EJBJ7A"JA Jr   rb   rQ   )rc   r   r   rT   topr   rV   r   re   rf   rg   r   r   rh   ri   rj   rk   s         r   expandBlossomz*max_weight_matching.<locals>.expandBlossom  sb    [	 [	D !X&')C Xa23 		 r   c                     	fd} || |      g}|r5|d   }|D ]  }|j                   ||         n |j                          |r4y y )Nc              3     K   |}
|   | k7  r
|   }
|   | k7  rt        |      r||f | j                  j                  |      x}}|dz  r|t        | j                        z  }d}nd}|dk7  r||z  }| j                  |   }|dk(  r| j                  |   \  }}n| j                  |dz
     \  }}t        |      r||f ||z  }| j                  |   }t        |      r||f ||<   ||<   |dk7  r| j                  |d  | j                  d | z   | _        | j                  |d  | j                  d | z   | _        	| j                  d      	| <   	|    |k(  sJ y w)Nr2   r   r   )r(   rN   r   r*   r   )rc   r   rU   r~   r   r   r:   xrV   rg   r   rk   s           r   r   z=max_weight_matching.<locals>.augmentBlossom.<locals>._recurse  s     A"a'!!$  "a' !W%!fHHNN1%%A1uS]" q&U
HHQKA:771:DAq771q5>DAqa)a&LU
HHQKa)a&LQQ# q&& xx|ahhrl2AHggabkAGGBQK/AG(!5KNq>Q&&&s   E#CE#;A(E#r   r   )
rc   r   r   rT   r   argsrV   rg   r   rk   s
         r   augmentBlossomz+max_weight_matching.<locals>.augmentBlossom  sW    )	'` !Q )C Xt_- 		 r   c                 J   | |f|| ffD ]  \  }}	 
|   }|   dk(  sJ |   	|   vs|   d   	|      k(  sJ t        |      r	 ||       ||<   |   U|   d   }
|   }|   dk(  sJ |   \  }}	|   |k(  sJ t        |      r	 ||       ||<    y )Nr2   r   r#   )r(   )r   r:   r   r   bsrU   btrV   r   rg   rh   ri   rj   rk   s          r   augmentMatchingz,max_weight_matching.<locals>.augmentMatchingW  s   VaV$ 	DAq q\RyA~%~!"-+b/2MbM!$[_(==  b'*"2q)QR=(bM!$q\RyA~%~ }1"2!+++b'*"2q)Q3 		r   c                  ,   r%t        dt        j                                      } nd} t        j                               | z   dk\  sJ t              dk(  st        j                               dk\  sJ j	                  d      D ]  \  }}}|j                  d      }||k(  r |   |   z   d|z  z
  }|g}|g}|d       |j                  |d             |d       |d       |j                  |d             |d       |j                          |j                          t        ||      D ]  \  }}	||	k7  r n|d|   z  z  } |dk\  sJ j                  |      |k(  sj                  |      |k(  s|   |k(  r|   |k(  sJ |dk(  rJ  D ]  }
|
v r|
   | z   dk(  rJ  D ]T  }|   dkD  st        |j                        dz  dk(  sJ |j                  dd d   D ]  \  }}|   |k(  r	|   |k(  rJ  V y )Nr   TrY   r2   r#   r   )	r?   minrv   r*   r   r^   rb   rs   zip)vdualoffsetr~   r   dwtr   	iblossoms	jblossomsbir   r   rc   r   r   r   r_   gnodesrk   r1   r.   s               r   verifyOptimumz*max_weight_matching.<locals>.verifyOptimumx  s    a#gnn&6"7!78KK7>>#${2a777;1$K,>,>,@(AQ(FFF wwDw) 	GAq!vq!BAv
WQZ'!b&0AII	".:  y}!=>  	".:	".:  y}!=>  	".:i3 )B8QR(() 6M6xx{a488A;!#3Aw!|Q144Avv)	,  	@AI'!*{":a"???	@  	9A1~!177|a'1,,,GGADqDM 9DAq7a<DGqL889	9r   r#   r   g       @   rn   F)ru   r   r   r^   strtypesplitr)   r   r   clearrO   rQ   rt   r   rv   r   r?   rb   keysr!   )+r   r1   r.   	maxweight
allintegerr~   r   r   r   rq   r   r   r   r   rc   r   	augmentedr:   rx   ry   r   rd   	deltatypedelta	deltaedgedeltablossomrV   rK   r   re   r   rf   rg   r   r   r_   r   rh   ri   rj   rk   rl   r`   s+   ```                       @@@@@@@@@@@@@@@@@r   r
   r
   B  s   X< < 8 !WFu IJ777% U1aUU616b9nITSb]%8%8%=a%@O%S
	U D E I S()I
 VVD\23M s66*+K H 3vvi012G
 K
 I ED
- -2   J\! \!~o oh=B B)9 )9Z  	 	 	!A AM	!
 	 a  	(A599Yq\#:#BAq$'	(
 	 	IIKYq\*a/// Q 41AAv "1B"1BRx 1vY.!&q!!Q;DHHIq!f-	1a&0A1v* 99R=0 (1a0"YYr]a/ $/q!#4D#61 !+4A 6 !01 5,-	 %"YYq\1
 $)9>1>'(E!H,-q6IaL2!+ $<<+3vxPR|@T7T,-q6HRL1- $<<?2fuhqk?R6R+,a&HQKi41 	x  I/33E3I "	GNN,- WWY 099Yq\*2x||A7Rx{+A B!e) !$%	$,QK	0 # 0!!$,		!) Q3"HQK0F! &
q000"aK"SL B!e) !$%	$,QK	0$ ! %!!$,		!)"bKNU,B'NE !I#$L% B &%~	As7>>#345  (99Yq\*a/AJ%'JYYy|,1AJ%'J( ! 0 #+yy|q(#A%/1*#A%/0 A~a"AYq\*a///8<<	1a&!Iq!f$5Qa"A8<<	1a&!Iq!f$5Yq\*a///QalE2Q Z  	&AQ=A%%%	&  k&&() 	'A#Q'EIIaLA,=+a.TUBUa&		'c p %%r   r>   )Fr.   )rJ   collectionsr   	itertoolsr   r   networkxr   networkx.utilsr   __all___dispatchabler   r!   r   r   r	   r   r
   r7   r   r   <module>r      s!   A  *  . \"Z $  ! #$N2 9 9x : :z 0  0 f \"Z X&7I ' ! #7It \"Z X&{& ' ! #{&r   