U
    :vf
                     @   s"   d Z ddlmZ G dd dZdS )z
Union-find data structure.
    )groupsc                   @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )	UnionFinda  Union-find data structure.

    Each unionFind instance X maintains a family of disjoint sets of
    hashable objects, supporting the following two methods:

    - X[item] returns a name for the set containing the given item.
      Each set is named by an arbitrarily-chosen one of its members; as
      long as the set remains unchanged it will keep the same name. If
      the item is not yet part of a set in X, a new singleton set is
      created for it.

    - X.union(item1, item2, ...) merges the sets containing each item
      into a single larger set.  If any item is not yet part of a set
      in X, it is added to X as one of the members of the merged set.

      Union-find data structure. Based on Josiah Carlson's code,
      https://code.activestate.com/recipes/215912/
      with significant additional changes by D. Eppstein.
      http://www.ics.uci.edu/~eppstein/PADS/UnionFind.py

    Nc                 C   s:   |dkrd}i | _ i | _|D ]}d| j|< || j |< qdS )zCreate a new empty union-find structure.

        If *elements* is an iterable, this structure will be initialized
        with the discrete partition on the given set of elements.

        N    )parentsweights)selfelementsxr   r   =/tmp/pip-unpacked-wheel-_lngutwb/networkx/utils/union_find.py__init__   s    
zUnionFind.__init__c                 C   sj   || j kr"|| j |< d| j|< |S g }| j | }||krR|| |}| j | }q0|D ]}|| j |< qV|S )z:Find and return the name of the set containing the object.r   )r   r   append)r   objectpathrootZancestorr   r   r   __getitem__.   s    




zUnionFind.__getitem__c                 C   s
   t | jS )zBIterate through all items ever found or unioned by this structure.)iterr   r   r   r   r   __iter__D   s    zUnionFind.__iter__c                 c   s,   | j D ]}| | }qt| j  E dH  dS )a]  Iterates over the sets stored in this structure.

        For example::

            >>> partition = UnionFind("xyz")
            >>> sorted(map(sorted, partition.to_sets()))
            [['x'], ['y'], ['z']]
            >>> partition.union("x", "y")
            >>> sorted(map(sorted, partition.to_sets()))
            [['x', 'y'], ['z']]

        N)r   r   values)r   r
   _r   r   r   to_setsH   s    

zUnionFind.to_setsc                    s|   t t fdd|D  fdddd}zt|}W n tk
rJ   Y dS X |D ]&} j|   j| 7  < | j|< qPdS )z8Find the sets containing the objects and merge them all.c                    s   h | ]} | qS r   r   ).0r
   r   r   r   	<setcomp>`   s     z"UnionFind.union.<locals>.<setcomp>c                    s
    j |  S )N)r   )rr   r   r   <lambda>`       z!UnionFind.union.<locals>.<lambda>T)keyreverseN)r   sortednextStopIterationr   r   )r   Zobjectsrootsr   r   r   r   r   union[   s     
 zUnionFind.union)N)	__name__
__module____qualname____doc__r   r   r   r   r#   r   r   r   r   r      s   
r   N)r'   Znetworkx.utilsr   r   r   r   r   r   <module>   s   