The doc modules clearly needs some restructuring...
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