To be on the safe side...
     2 #ifndef HUGO_UNION_FIND_H
 
     3 #define HUGO_UNION_FIND_H
 
    14   template <typename T, typename TIntMap>
 
    18     typedef T ElementType;
 
    19     typedef std::pair<int,int> PairType;
 
    22     std::vector<PairType> data;
 
    26     UnionFind(TIntMap& m) : map(m) {}
 
    37       while ( (next = data[comp].first) != comp) {
 
    40       while ( (next = data[comp0].first) != comp) {
 
    41 	data[comp0].first = comp;
 
    51       data.push_back(std::make_pair(n, 1));
 
    64       if ( data[ca].second > data[cb].second ) {
 
    66 	data[ca].second += data[cb].second;
 
    70 	data[cb].second += data[ca].second;
 
    78       return data[ca].second;
 
    86   /*******************************************************/
 
    91   struct UnionFindEnumItem {
 
    93     typedef std::list<UnionFindEnumItem> ItemList;
 
    94     typedef std::list<ItemList> ClassList;
 
    95     typedef typename ItemList::iterator IIter;
 
    96     typedef typename ClassList::iterator CIter;
 
   103     UnionFindEnumItem() {}
 
   104     UnionFindEnumItem(const T &_me, CIter _my_class): 
 
   105       me(_me), size(1), my_class(_my_class) {}
 
   108   template <typename T, template <typename Item> class Map>
 
   109   class UnionFindEnum {
 
   111     typedef std::list<UnionFindEnumItem<T> > ItemList;
 
   112     typedef std::list<ItemList> ClassList;
 
   113     typedef typename ItemList::iterator IIter;
 
   114     typedef typename ItemList::const_iterator IcIter;
 
   115     typedef typename ClassList::iterator CIter;
 
   116     typedef typename ClassList::const_iterator CcIter;
 
   119     typedef T ElementType;
 
   120     typedef UnionFindEnumItem<T> ItemType;
 
   121     typedef Map< IIter > MapType;
 
   127     //    IIter where(const T &a) { return m[a]; }
 
   128     //    IIter parent(IIter a) { return a->parent; }
 
   129     //    P sibling(P a) { return &m[a->sibling]; }
 
   131     IIter _find(IIter a) const {
 
   134       while( (next = comp->parent) != comp ) {
 
   139       while( (next = comp1->parent) != comp ) {
 
   140 	comp1->parent = comp->parent;
 
   147     UnionFindEnum(MapType& _m) : m(_m) {}
 
   149     void insert(const T &a)
 
   153       classes.push_back(ItemList());
 
   154       CIter aclass = classes.end();
 
   157       ItemList &alist = *aclass;
 
   158       alist.push_back(ItemType(a, aclass));
 
   159       IIter ai = alist.begin();
 
   166     T find(const T &a) const {
 
   167       return _find(m[a])->me;
 
   170     bool join(T a, T b) {
 
   172       IIter ca = _find(m[a]);
 
   173       IIter cb = _find(m[b]);
 
   179       if ( ca->size > cb->size ) {
 
   181 	cb->parent = ca->parent;
 
   182 	ca->size += cb->size;
 
   184 	ItemList &alist = *ca->my_class;
 
   185 	alist.splice(alist.end(),*cb->my_class);
 
   187 	classes.erase(cb->my_class);
 
   192 	ca->parent = cb->parent;
 
   193 	cb->size += ca->size;
 
   195 	ItemList &blist = *cb->my_class;
 
   196 	blist.splice(blist.end(),*ca->my_class);
 
   198 	classes.erase(ca->my_class);
 
   205     int size(const T &a) const {
 
   206       return _find(m[a])->size;
 
   210     void split(const T &a) {
 
   212       IIter ca = _find(m[a]);
 
   217       CIter aclass = ca->my_class;
 
   219       for(IIter curr = ca; ++curr != aclass->end(); curr=ca) {
 
   220 	classes.push_back(ItemList());
 
   221 	CIter nl = --classes.end();
 
   222 	nl->splice(nl->end(), *aclass, curr);
 
   233     void erase(const T &a) {
 
   238       IIter la = _find(ma);
 
   240 	if (ma -> size == 1){
 
   241 	  classes.erase(ma->my_class);
 
   246 	la->size = ma->size - 1; 
 
   247 	la->my_class = ma->my_class;	
 
   250       for (IIter i = la; i != la->my_class->end(); ++i) {
 
   254       la->my_class->erase(ma);
 
   258     void eraseClass(const T &a) {
 
   262       CIter c = _find(ma)->my_class;
 
   263       for (IIter i=c->begin(); i!=c->end(); ++i)
 
   266       classes.erase(_find(ma)->my_class);
 
   271       friend class UnionFindEnum;
 
   275       ClassIt(Invalid): i(0) {}
 
   278       operator const T& () const { 
 
   279 	ItemList const &ll = *i;
 
   280 	return (ll.begin())->me; }
 
   281       bool operator == (ClassIt it) const {
 
   284       bool operator != (ClassIt it) const {
 
   287       bool operator < (ClassIt it) const {
 
   291       bool valid() const { return i != 0; }
 
   293       void first(const ClassList &l) { i = l.begin(); validate(l); }
 
   294       void next(const ClassList &l) {
 
   298       void validate(const ClassList &l) {
 
   305     ClassIt& first(ClassIt& it) const {
 
   310     bool valid(ClassIt const &it) const {
 
   314     ClassIt& next(ClassIt& it) const {
 
   321       friend class UnionFindEnum;
 
   326       ItemIt(Invalid): i(0) {}
 
   329       operator const T& () const { return i->me; }
 
   330       bool operator == (ItemIt it) const {
 
   333       bool operator != (ItemIt it) const {
 
   336       bool operator < (ItemIt it) const {
 
   340       bool valid() const { return i != 0; }
 
   342       void first(const ItemList &il) { l=&il; i = l->begin(); validate(); }
 
   354     ItemIt& first(ItemIt& it, const T& a) const {
 
   355       it.first( * _find(m[a])->my_class );
 
   359     bool valid(ItemIt const &it) const {
 
   363     ItemIt& next(ItemIt& it) const {
 
   374 #endif //HUGO_UNION_FIND_H