34 namespace lemon { |
34 namespace lemon { |
35 |
35 |
36 //! \addtogroup auxdat |
36 //! \addtogroup auxdat |
37 //! @{ |
37 //! @{ |
38 |
38 |
39 /** |
39 /// \brief A \e Union-Find data structure implementation |
40 * \brief A \e Union-Find data structure implementation |
40 /// |
41 * |
41 /// The class implements the \e Union-Find data structure. |
42 * The class implements the \e Union-Find data structure. |
42 /// The union operation uses rank heuristic, while |
43 * The union operation uses rank heuristic, while |
43 /// the find operation uses path compression. |
44 * the find operation uses path compression. |
44 /// This is a very simple but efficient implementation, providing |
45 * This is a very simple but efficient implementation, providing |
45 /// only four methods: join (union), find, insert and size. |
46 * only four methods: join (union), find, insert and size. |
46 /// For more features see the \ref UnionFindEnum class. |
47 * For more features see the \ref UnionFindEnum class. |
47 /// |
48 * |
48 /// It is primarily used in Kruskal algorithm for finding minimal |
49 * It is primarily used in Kruskal algorithm for finding minimal |
49 /// cost spanning tree in a graph. |
50 * cost spanning tree in a graph. |
50 /// \sa kruskal() |
51 * \sa kruskal() |
51 /// |
52 * |
52 /// \pre You need to add all the elements by the \ref insert() |
53 * \pre The elements are automatically added only if the map |
53 /// method. |
54 * given to the constructor was filled with -1's. Otherwise you |
54 template <typename Item, typename ItemIntMap> |
55 * need to add all the elements by the \ref insert() method. |
|
56 * \bug It is not clear what the constructor parameter is used for. |
|
57 */ |
|
58 |
|
59 template <typename T, typename TIntMap> |
|
60 class UnionFind { |
55 class UnionFind { |
61 |
56 |
62 public: |
57 public: |
63 typedef T ElementType; |
58 typedef Item ElementType; |
64 typedef std::pair<int,int> PairType; |
|
65 |
59 |
66 private: |
60 private: |
67 std::vector<PairType> data; |
61 // If the items vector stores negative value for an item then |
68 TIntMap& map; |
62 // that item is root item and it has -items[it] component size. |
|
63 // Else the items[it] contains the index of the parent. |
|
64 std::vector<int> items; |
|
65 ItemIntMap& index; |
|
66 |
|
67 bool rep(int idx) const { |
|
68 return items[idx] < 0; |
|
69 } |
|
70 |
|
71 int repIndex(int idx) const { |
|
72 int k = idx; |
|
73 while (!rep(k)) { |
|
74 k = items[k] ; |
|
75 } |
|
76 while (idx != k) { |
|
77 int next = items[idx]; |
|
78 const_cast<int&>(items[idx]) = k; |
|
79 idx = next; |
|
80 } |
|
81 return k; |
|
82 } |
69 |
83 |
70 public: |
84 public: |
71 UnionFind(TIntMap& m) : map(m) {} |
85 |
72 |
86 /// \brief Constructor |
73 /** |
87 /// |
74 * \brief Returns the index of the element's component. |
88 /// Constructor of the UnionFind class. You should give an item to |
75 * |
89 /// integer map which will be used from the data structure. If you |
76 * The method returns the index of the element's component. |
90 /// modify directly this map that may cause segmentation fault, |
77 * This is an integer between zero and the number of inserted elements. |
91 /// invalid data structure, or infinite loop when you use again |
78 */ |
92 /// the union-find. |
79 |
93 UnionFind(ItemIntMap& m) : index(m) {} |
80 int find(T a) |
94 |
81 { |
95 /// \brief Returns the index of the element's component. |
82 int comp0 = map[a]; |
96 /// |
83 if (comp0 < 0) { |
97 /// The method returns the index of the element's component. |
84 return insert(a); |
98 /// This is an integer between zero and the number of inserted elements. |
85 } |
99 /// |
86 int comp = comp0; |
100 int find(const Item& a) { |
87 int next; |
101 return repIndex(index[a]); |
88 while ( (next = data[comp].first) != comp) { |
102 } |
89 comp = next; |
103 |
90 } |
104 /// \brief Inserts a new element into the structure. |
91 while ( (next = data[comp0].first) != comp) { |
105 /// |
92 data[comp0].first = comp; |
106 /// This method inserts a new element into the data structure. |
93 comp0 = next; |
107 /// |
94 } |
108 /// The method returns the index of the new component. |
95 |
109 int insert(const Item& a) { |
96 return comp; |
110 int n = items.size(); |
97 } |
111 items.push_back(-1); |
98 |
112 index.set(a,n); |
99 /** |
|
100 * \brief Inserts a new element into the structure. |
|
101 * |
|
102 * This method inserts a new element into the data structure. |
|
103 * |
|
104 * It is not required to use this method: |
|
105 * if the map given to the constructor was filled |
|
106 * with -1's then it is called automatically |
|
107 * on the first \ref find or \ref join. |
|
108 * |
|
109 * The method returns the index of the new component. |
|
110 */ |
|
111 |
|
112 int insert(T a) |
|
113 { |
|
114 int n = data.size(); |
|
115 data.push_back(std::make_pair(n, 1)); |
|
116 map.set(a,n); |
|
117 return n; |
113 return n; |
118 } |
114 } |
119 |
115 |
120 /** |
116 /// \brief Joining the components of element \e a and element \e b. |
121 * \brief Joining the components of element \e a and element \e b. |
117 /// |
122 * |
118 /// This is the \e union operation of the Union-Find structure. |
123 * This is the \e union operation of the Union-Find structure. |
119 /// Joins the component of element \e a and component of |
124 * Joins the component of element \e a and component of |
120 /// element \e b. If \e a and \e b are in the same component then |
125 * element \e b. If \e a and \e b are in the same component then |
121 /// it returns false otherwise it returns true. |
126 * it returns false otherwise it returns true. |
122 bool join(const Item& a, const Item& b) { |
127 */ |
123 int ka = repIndex(index[a]); |
128 |
124 int kb = repIndex(index[b]); |
129 bool join(T a, T b) |
125 |
130 { |
126 if ( ka == kb ) |
131 int ca = find(a); |
|
132 int cb = find(b); |
|
133 |
|
134 if ( ca == cb ) |
|
135 return false; |
127 return false; |
136 |
128 |
137 if ( data[ca].second > data[cb].second ) { |
129 if (items[ka] < items[kb]) { |
138 data[cb].first = ca; |
130 items[ka] += items[kb]; |
139 data[ca].second += data[cb].second; |
131 items[kb] = ka; |
140 } |
132 } else { |
141 else { |
133 items[kb] += items[ka]; |
142 data[ca].first = cb; |
134 items[ka] = kb; |
143 data[cb].second += data[ca].second; |
|
144 } |
135 } |
145 return true; |
136 return true; |
146 } |
137 } |
147 |
138 |
148 /** |
139 /// \brief Returns the size of the component of element \e a. |
149 * \brief Returns the size of the component of element \e a. |
140 /// |
150 * |
141 /// Returns the size of the component of element \e a. |
151 * Returns the size of the component of element \e a. |
142 int size(const Item& a) { |
152 */ |
143 int k = repIndex(index[a]); |
153 |
144 return - items[k]; |
154 int size(T a) |
|
155 { |
|
156 int ca = find(a); |
|
157 return data[ca].second; |
|
158 } |
145 } |
159 |
146 |
160 }; |
147 }; |
161 |
148 |
162 |
149 |
163 |
150 /// \brief A \e Union-Find data structure implementation which |
164 |
151 /// is able to enumerate the components. |
165 /*******************************************************/ |
152 /// |
166 |
153 /// The class implements a \e Union-Find data structure |
167 |
154 /// which is able to enumerate the components and the items in |
168 #ifdef DEVELOPMENT_DOCS |
155 /// a component. If you don't need this feature then perhaps it's |
169 |
156 /// better to use the \ref UnionFind class which is more efficient. |
170 /** |
157 /// |
171 * \brief The auxiliary class for the \ref UnionFindEnum class. |
158 /// The union operation uses rank heuristic, while |
172 * |
159 /// the find operation uses path compression. |
173 * In the \ref UnionFindEnum class all components are represented as |
160 /// |
174 * a std::list. |
161 /// \pre You need to add all the elements by the \ref insert() |
175 * Items of these lists are UnionFindEnumItem structures. |
162 /// method. |
176 * |
163 /// |
177 * The class has four fields: |
164 template <typename _Item, typename _ItemIntMap> |
178 * - T me - the actual element |
165 class UnionFindEnum { |
179 * - IIter parent - the parent of the element in the union-find structure |
166 public: |
180 * - int size - the size of the component of the element. |
167 |
181 * Only valid if the element |
168 typedef _Item Item; |
182 * is the leader of the component. |
169 typedef _ItemIntMap ItemIntMap; |
183 * - CIter my_class - pointer into the list of components |
170 |
184 * pointing to the component of the element. |
171 private: |
185 * Only valid if the element is the leader of the component. |
172 |
186 */ |
173 // If the parent stores negative value for an item then that item |
187 |
174 // is root item and it has -items[it].parent component size. Else |
188 #endif |
175 // the items[it].parent contains the index of the parent. |
189 |
176 // |
190 template <typename T> |
177 // The \c nextItem and \c prevItem provides the double-linked |
191 struct UnionFindEnumItem { |
178 // cyclic list of one component's items. The \c prevClass and |
192 |
179 // \c nextClass gives the double linked list of the representant |
193 typedef std::list<UnionFindEnumItem> ItemList; |
180 // items. |
194 typedef std::list<ItemList> ClassList; |
181 struct ItemT { |
195 typedef typename ItemList::iterator IIter; |
182 int parent; |
196 typedef typename ClassList::iterator CIter; |
183 Item item; |
197 |
184 |
198 T me; |
185 int nextItem, prevItem; |
199 IIter parent; |
186 int nextClass, prevClass; |
200 int size; |
187 }; |
201 CIter my_class; |
188 |
202 |
189 std::vector<ItemT> items; |
203 UnionFindEnumItem() {} |
190 ItemIntMap& index; |
204 UnionFindEnumItem(const T &_me, CIter _my_class): |
191 |
205 me(_me), size(1), my_class(_my_class) {} |
192 int firstClass; |
|
193 |
|
194 |
|
195 bool rep(int idx) const { |
|
196 return items[idx].parent < 0; |
|
197 } |
|
198 |
|
199 int repIndex(int idx) const { |
|
200 int k = idx; |
|
201 while (!rep(k)) { |
|
202 k = items[k].parent; |
|
203 } |
|
204 while (idx != k) { |
|
205 int next = items[idx].parent; |
|
206 const_cast<int&>(items[idx].parent) = k; |
|
207 idx = next; |
|
208 } |
|
209 return k; |
|
210 } |
|
211 |
|
212 void unlaceClass(int k) { |
|
213 if (items[k].prevClass != -1) { |
|
214 items[items[k].prevClass].nextClass = items[k].nextClass; |
|
215 } else { |
|
216 firstClass = items[k].nextClass; |
|
217 } |
|
218 if (items[k].nextClass != -1) { |
|
219 items[items[k].nextClass].prevClass = items[k].prevClass; |
|
220 } |
|
221 } |
|
222 |
|
223 void spliceItems(int ak, int bk) { |
|
224 items[items[ak].prevItem].nextItem = bk; |
|
225 items[items[bk].prevItem].nextItem = ak; |
|
226 int tmp = items[ak].prevItem; |
|
227 items[ak].prevItem = items[bk].prevItem; |
|
228 items[bk].prevItem = tmp; |
|
229 |
|
230 } |
|
231 |
|
232 public: |
|
233 |
|
234 UnionFindEnum(ItemIntMap& _index) |
|
235 : items(), index(_index), firstClass(-1) {} |
|
236 |
|
237 /// \brief Inserts the given element into a new component. |
|
238 /// |
|
239 /// This method creates a new component consisting only of the |
|
240 /// given element. |
|
241 /// |
|
242 void insert(const Item& item) { |
|
243 ItemT t; |
|
244 |
|
245 int idx = items.size(); |
|
246 index.set(item, idx); |
|
247 |
|
248 t.nextItem = idx; |
|
249 t.prevItem = idx; |
|
250 t.item = item; |
|
251 t.parent = -1; |
|
252 |
|
253 t.nextClass = firstClass; |
|
254 if (firstClass != -1) { |
|
255 items[firstClass].prevClass = idx; |
|
256 } |
|
257 t.prevClass = -1; |
|
258 firstClass = idx; |
|
259 |
|
260 items.push_back(t); |
|
261 } |
|
262 |
|
263 /// \brief Inserts the given element into the component of the others. |
|
264 /// |
|
265 /// This methods inserts the element \e a into the component of the |
|
266 /// element \e comp. |
|
267 void insert(const Item& item, const Item& comp) { |
|
268 int k = repIndex(index[comp]); |
|
269 ItemT t; |
|
270 |
|
271 int idx = items.size(); |
|
272 index.set(item, idx); |
|
273 |
|
274 t.prevItem = k; |
|
275 t.nextItem = items[k].nextItem; |
|
276 items[items[k].nextItem].prevItem = idx; |
|
277 items[k].nextItem = idx; |
|
278 |
|
279 t.item = item; |
|
280 t.parent = k; |
|
281 |
|
282 --items[k].parent; |
|
283 |
|
284 items.push_back(t); |
|
285 } |
|
286 |
|
287 /// \brief Finds the leader of the component of the given element. |
|
288 /// |
|
289 /// The method returns the leader of the component of the given element. |
|
290 const Item& find(const Item &item) const { |
|
291 return items[repIndex(index[item])].item; |
|
292 } |
|
293 |
|
294 /// \brief Joining the component of element \e a and element \e b. |
|
295 /// |
|
296 /// This is the \e union operation of the Union-Find structure. |
|
297 /// Joins the component of element \e a and component of |
|
298 /// element \e b. If \e a and \e b are in the same component then |
|
299 /// returns false else returns true. |
|
300 bool join(const Item& a, const Item& b) { |
|
301 |
|
302 int ak = repIndex(index[a]); |
|
303 int bk = repIndex(index[b]); |
|
304 |
|
305 if (ak == bk) { |
|
306 return false; |
|
307 } |
|
308 |
|
309 if ( items[ak].parent < items[bk].parent ) { |
|
310 unlaceClass(bk); |
|
311 items[ak].parent += items[bk].parent; |
|
312 items[bk].parent = ak; |
|
313 } else { |
|
314 unlaceClass(bk); |
|
315 items[bk].parent += items[ak].parent; |
|
316 items[ak].parent = bk; |
|
317 } |
|
318 spliceItems(ak, bk); |
|
319 |
|
320 return true; |
|
321 } |
|
322 |
|
323 /// \brief Returns the size of the component of element \e a. |
|
324 /// |
|
325 /// Returns the size of the component of element \e a. |
|
326 int size(const Item &item) const { |
|
327 return - items[repIndex(index[item])].parent; |
|
328 } |
|
329 |
|
330 /// \brief Splits up the component of the element. |
|
331 /// |
|
332 /// Splitting the component of the element into sigleton |
|
333 /// components (component of size one). |
|
334 void split(const Item &item) { |
|
335 int k = repIndex(index[item]); |
|
336 int idx = items[k].nextItem; |
|
337 while (idx != k) { |
|
338 int next = items[idx].nextItem; |
|
339 |
|
340 items[idx].parent = -1; |
|
341 items[idx].prevItem = idx; |
|
342 items[idx].nextItem = idx; |
|
343 |
|
344 items[idx].nextClass = firstClass; |
|
345 items[firstClass].prevClass = idx; |
|
346 firstClass = idx; |
|
347 |
|
348 idx = next; |
|
349 } |
|
350 |
|
351 items[idx].parent = -1; |
|
352 items[idx].prevItem = idx; |
|
353 items[idx].nextItem = idx; |
|
354 |
|
355 items[firstClass].prevClass = -1; |
|
356 } |
|
357 |
|
358 /// \brief Sets the given element to the leader element of its component. |
|
359 /// |
|
360 /// Sets the given element to the leader element of its component. |
|
361 void makeRep(const Item &item) { |
|
362 int nk = index[item]; |
|
363 int k = repIndex(nk); |
|
364 if (nk == k) return; |
|
365 |
|
366 if (items[k].prevClass != -1) { |
|
367 items[items[k].prevClass].nextClass = nk; |
|
368 } else { |
|
369 firstClass = nk; |
|
370 } |
|
371 if (items[k].nextClass != -1) { |
|
372 items[items[k].nextClass].prevClass = nk; |
|
373 } |
|
374 |
|
375 int idx = items[k].nextItem; |
|
376 while (idx != k) { |
|
377 items[idx].parent = nk; |
|
378 idx = items[idx].nextItem; |
|
379 } |
|
380 |
|
381 items[nk].parent = items[k].parent; |
|
382 items[k].parent = nk; |
|
383 } |
|
384 |
|
385 /// \brief Removes the given element from the structure. |
|
386 /// |
|
387 /// Removes the element from its component and if the component becomes |
|
388 /// empty then removes that component from the component list. |
|
389 /// |
|
390 /// \warning It is an error to remove an element which is not in |
|
391 /// the structure. |
|
392 void erase(const Item &item) { |
|
393 int idx = index[item]; |
|
394 if (rep(idx)) { |
|
395 int k = idx; |
|
396 if (items[k].parent == -1) { |
|
397 unlaceClass(idx); |
|
398 return; |
|
399 } else { |
|
400 int nk = items[k].nextItem; |
|
401 if (items[k].prevClass != -1) { |
|
402 items[items[k].prevClass].nextClass = nk; |
|
403 } else { |
|
404 firstClass = nk; |
|
405 } |
|
406 if (items[k].nextClass != -1) { |
|
407 items[items[k].nextClass].prevClass = nk; |
|
408 } |
|
409 |
|
410 int idx = items[k].nextItem; |
|
411 while (idx != k) { |
|
412 items[idx].parent = nk; |
|
413 idx = items[idx].nextItem; |
|
414 } |
|
415 |
|
416 items[nk].parent = items[k].parent + 1; |
|
417 } |
|
418 } else { |
|
419 |
|
420 int k = repIndex(idx); |
|
421 idx = items[k].nextItem; |
|
422 while (idx != k) { |
|
423 items[idx].parent = k; |
|
424 idx = items[idx].nextItem; |
|
425 } |
|
426 |
|
427 ++items[k].parent; |
|
428 } |
|
429 |
|
430 idx = index[item]; |
|
431 items[items[idx].prevItem].nextItem = items[idx].nextItem; |
|
432 items[items[idx].nextItem].prevItem = items[idx].prevItem; |
|
433 |
|
434 } |
|
435 |
|
436 /// \brief Moves the given element to another component. |
|
437 /// |
|
438 /// This method moves the element \e a from its component |
|
439 /// to the component of \e comp. |
|
440 /// If \e a and \e comp are in the same component then |
|
441 /// it returns false otherwise it returns true. |
|
442 bool move(const Item &item, const Item &comp) { |
|
443 if (repIndex(index[item]) == repIndex(index[comp])) return false; |
|
444 erase(item); |
|
445 insert(item, comp); |
|
446 return true; |
|
447 } |
|
448 |
|
449 |
|
450 /// \brief Removes the component of the given element from the structure. |
|
451 /// |
|
452 /// Removes the component of the given element from the structure. |
|
453 /// |
|
454 /// \warning It is an error to give an element which is not in the |
|
455 /// structure. |
|
456 void eraseClass(const Item &item) { |
|
457 unlaceClass(repIndex(index[item])); |
|
458 } |
|
459 |
|
460 /// \brief Lemon style iterator for the representant items. |
|
461 /// |
|
462 /// ClassIt is a lemon style iterator for the components. It iterates |
|
463 /// on the representant items of the classes. |
|
464 class ClassIt { |
|
465 public: |
|
466 /// \brief Constructor of the iterator |
|
467 /// |
|
468 /// Constructor of the iterator |
|
469 ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) { |
|
470 idx = unionFind->firstClass; |
|
471 } |
|
472 |
|
473 /// \brief Constructor to get invalid iterator |
|
474 /// |
|
475 /// Constructor to get invalid iterator |
|
476 ClassIt(Invalid) : unionFind(0), idx(-1) {} |
|
477 |
|
478 /// \brief Increment operator |
|
479 /// |
|
480 /// It steps to the next representant item. |
|
481 ClassIt& operator++() { |
|
482 idx = unionFind->items[idx].nextClass; |
|
483 return *this; |
|
484 } |
|
485 |
|
486 /// \brief Conversion operator |
|
487 /// |
|
488 /// It converts the iterator to the current representant item. |
|
489 operator const Item&() const { |
|
490 return unionFind->items[idx].item; |
|
491 } |
|
492 |
|
493 /// \brief Equality operator |
|
494 /// |
|
495 /// Equality operator |
|
496 bool operator==(const ClassIt& i) { |
|
497 return i.idx == idx; |
|
498 } |
|
499 |
|
500 /// \brief Inequality operator |
|
501 /// |
|
502 /// Inequality operator |
|
503 bool operator!=(const ClassIt& i) { |
|
504 return i.idx != idx; |
|
505 } |
|
506 |
|
507 private: |
|
508 const UnionFindEnum* unionFind; |
|
509 int idx; |
|
510 }; |
|
511 |
|
512 /// \brief Lemon style iterator for the items of a component. |
|
513 /// |
|
514 /// ClassIt is a lemon style iterator for the components. It iterates |
|
515 /// on the items of a class. By example if you want to iterate on |
|
516 /// each items of each classes then you may write the next code. |
|
517 ///\code |
|
518 /// for (ClassIt cit(ufe); cit != INVALID; ++cit) { |
|
519 /// std::cout << "Class: "; |
|
520 /// for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) { |
|
521 /// std::cout << toString(iit) << ' ' << std::endl; |
|
522 /// } |
|
523 /// std::cout << std::endl; |
|
524 /// } |
|
525 ///\endcode |
|
526 class ItemIt { |
|
527 public: |
|
528 /// \brief Constructor of the iterator |
|
529 /// |
|
530 /// Constructor of the iterator. The iterator iterates |
|
531 /// on the class of the \c item. |
|
532 ItemIt(const UnionFindEnum& ufe, const Item& item) : unionFind(&ufe) { |
|
533 idx = unionFind->repIndex(unionFind->index[item]); |
|
534 } |
|
535 |
|
536 /// \brief Constructor to get invalid iterator |
|
537 /// |
|
538 /// Constructor to get invalid iterator |
|
539 ItemIt(Invalid) : unionFind(0), idx(-1) {} |
|
540 |
|
541 /// \brief Increment operator |
|
542 /// |
|
543 /// It steps to the next item in the class. |
|
544 ItemIt& operator++() { |
|
545 idx = unionFind->items[idx].nextItem; |
|
546 if (unionFind->rep(idx)) idx = -1; |
|
547 return *this; |
|
548 } |
|
549 |
|
550 /// \brief Conversion operator |
|
551 /// |
|
552 /// It converts the iterator to the current item. |
|
553 operator const Item&() const { |
|
554 return unionFind->items[idx].item; |
|
555 } |
|
556 |
|
557 /// \brief Equality operator |
|
558 /// |
|
559 /// Equality operator |
|
560 bool operator==(const ItemIt& i) { |
|
561 return i.idx == idx; |
|
562 } |
|
563 |
|
564 /// \brief Inequality operator |
|
565 /// |
|
566 /// Inequality operator |
|
567 bool operator!=(const ItemIt& i) { |
|
568 return i.idx != idx; |
|
569 } |
|
570 |
|
571 private: |
|
572 const UnionFindEnum* unionFind; |
|
573 int idx; |
|
574 }; |
|
575 |
206 }; |
576 }; |
207 |
577 |
208 |
578 |
209 /** |
|
210 * \brief A \e Union-Find data structure implementation which |
|
211 * is able to enumerate the components. |
|
212 * |
|
213 * The class implements a \e Union-Find data structure |
|
214 * which is able to enumerate the components and the items in |
|
215 * a component. If you don't need this feature then perhaps it's |
|
216 * better to use the \ref UnionFind class which is more efficient. |
|
217 * |
|
218 * The union operation uses rank heuristic, while |
|
219 * the find operation uses path compression. |
|
220 * |
|
221 * \pre You |
|
222 * need to add all the elements by the \ref insert() method. |
|
223 */ |
|
224 |
|
225 |
|
226 template <typename T, template <typename Item> class Map> |
|
227 class UnionFindEnum { |
|
228 |
|
229 typedef std::list<UnionFindEnumItem<T> > ItemList; |
|
230 typedef std::list<ItemList> ClassList; |
|
231 typedef typename ItemList::iterator IIter; |
|
232 typedef typename ItemList::const_iterator IcIter; |
|
233 typedef typename ClassList::iterator CIter; |
|
234 typedef typename ClassList::const_iterator CcIter; |
|
235 |
|
236 public: |
|
237 typedef T ElementType; |
|
238 typedef UnionFindEnumItem<T> ItemType; |
|
239 typedef Map< IIter > MapType; |
|
240 |
|
241 private: |
|
242 MapType& m; |
|
243 ClassList classes; |
|
244 |
|
245 IIter _find(IIter a) const { |
|
246 IIter comp = a; |
|
247 IIter next; |
|
248 while( (next = comp->parent) != comp ) { |
|
249 comp = next; |
|
250 } |
|
251 |
|
252 IIter comp1 = a; |
|
253 while( (next = comp1->parent) != comp ) { |
|
254 comp1->parent = comp->parent; |
|
255 comp1 = next; |
|
256 } |
|
257 return comp; |
|
258 } |
|
259 |
|
260 const ItemList& classOf(const T &a) const { |
|
261 return *_find(m[a])->my_class; |
|
262 } |
|
263 |
|
264 public: |
|
265 UnionFindEnum(MapType& _m) : m(_m) {} |
|
266 |
|
267 |
|
268 /** |
|
269 * \brief Inserts the given element into a new component. |
|
270 * |
|
271 * This method creates a new component consisting only of the |
|
272 * given element. |
|
273 */ |
|
274 |
|
275 void insert(const T &a) |
|
276 { |
|
277 |
|
278 |
|
279 classes.push_back(ItemList()); |
|
280 CIter aclass = classes.end(); |
|
281 --aclass; |
|
282 |
|
283 ItemList &alist = *aclass; |
|
284 alist.push_back(ItemType(a, aclass)); |
|
285 IIter ai = alist.begin(); |
|
286 |
|
287 ai->parent = ai; |
|
288 m.set(a, ai); |
|
289 |
|
290 } |
|
291 |
|
292 /** |
|
293 * \brief Inserts the given element into the component of the others. |
|
294 * |
|
295 * This methods inserts the element \e a into the component of the |
|
296 * element \e comp. |
|
297 */ |
|
298 |
|
299 void insert(const T &a, const T &comp) { |
|
300 |
|
301 IIter clit = _find(m[comp]); |
|
302 ItemList &c = *clit->my_class; |
|
303 c.push_back(ItemType(a,CIter())); |
|
304 IIter ai = c.end(); |
|
305 --ai; |
|
306 ai->parent = clit; |
|
307 m.set(a, ai); |
|
308 ++clit->size; |
|
309 } |
|
310 |
|
311 |
|
312 /** |
|
313 * \brief Finds the leader of the component of the given element. |
|
314 * |
|
315 * The method returns the leader of the component of the given element. |
|
316 */ |
|
317 |
|
318 T find(const T &a) const { |
|
319 return _find(m[a])->me; |
|
320 } |
|
321 |
|
322 |
|
323 /** |
|
324 * \brief Joining the component of element \e a and element \e b. |
|
325 * |
|
326 * This is the \e union operation of the Union-Find structure. |
|
327 * Joins the component of element \e a and component of |
|
328 * element \e b. If \e a and \e b are in the same component then |
|
329 * returns false else returns true. |
|
330 */ |
|
331 |
|
332 bool join(T a, T b) { |
|
333 |
|
334 IIter ca = _find(m[a]); |
|
335 IIter cb = _find(m[b]); |
|
336 |
|
337 if ( ca == cb ) { |
|
338 return false; |
|
339 } |
|
340 |
|
341 if ( ca->size > cb->size ) { |
|
342 |
|
343 cb->parent = ca->parent; |
|
344 ca->size += cb->size; |
|
345 |
|
346 ItemList &alist = *ca->my_class; |
|
347 alist.splice(alist.end(),*cb->my_class); |
|
348 |
|
349 classes.erase(cb->my_class); |
|
350 } |
|
351 else { |
|
352 |
|
353 ca->parent = cb->parent; |
|
354 cb->size += ca->size; |
|
355 |
|
356 ItemList &blist = *cb->my_class; |
|
357 blist.splice(blist.end(),*ca->my_class); |
|
358 |
|
359 classes.erase(ca->my_class); |
|
360 } |
|
361 |
|
362 return true; |
|
363 } |
|
364 |
|
365 |
|
366 /** |
|
367 * \brief Returns the size of the component of element \e a. |
|
368 * |
|
369 * Returns the size of the component of element \e a. |
|
370 */ |
|
371 |
|
372 int size(const T &a) const { |
|
373 return _find(m[a])->size; |
|
374 } |
|
375 |
|
376 |
|
377 /** |
|
378 * \brief Splits up the component of the element. |
|
379 * |
|
380 * Splitting the component of the element into sigleton |
|
381 * components (component of size one). |
|
382 */ |
|
383 |
|
384 void split(const T &a) { |
|
385 |
|
386 IIter ca = _find(m[a]); |
|
387 |
|
388 if ( ca->size == 1 ) |
|
389 return; |
|
390 |
|
391 CIter aclass = ca->my_class; |
|
392 |
|
393 for(IIter curr = ca; ++curr != aclass->end(); curr=ca) { |
|
394 classes.push_back(ItemList()); |
|
395 CIter nl = --classes.end(); |
|
396 nl->splice(nl->end(), *aclass, curr); |
|
397 |
|
398 curr->size=1; |
|
399 curr->parent=curr; |
|
400 curr->my_class = nl; |
|
401 } |
|
402 |
|
403 ca->size=1; |
|
404 return; |
|
405 } |
|
406 |
|
407 |
|
408 /** |
|
409 * \brief Sets the given element to the leader element of its component. |
|
410 * |
|
411 * Sets the given element to the leader element of its component. |
|
412 */ |
|
413 |
|
414 void makeRep(const T &a) { |
|
415 |
|
416 IIter ia = m[a]; |
|
417 IIter la = _find(ia); |
|
418 if (la == ia) return; |
|
419 |
|
420 ia->my_class = la->my_class; |
|
421 |
|
422 ia->size = la->size; |
|
423 |
|
424 CIter l = ia->my_class; |
|
425 l->splice(l->begin(),*l,ia); |
|
426 |
|
427 ia->parent = ia; |
|
428 la->parent = ia; |
|
429 } |
|
430 |
|
431 /** |
|
432 * \brief Moves the given element to another component. |
|
433 * |
|
434 * This method moves the element \e a from its component |
|
435 * to the component of \e comp. |
|
436 * If \e a and \e comp are in the same component then |
|
437 * it returns false otherwise it returns true. |
|
438 */ |
|
439 |
|
440 bool move(const T &a, const T &comp) { |
|
441 |
|
442 IIter ai = m[a]; |
|
443 IIter lai = _find(ai); |
|
444 IIter clit = _find(m[comp]); |
|
445 |
|
446 if (lai == clit) |
|
447 return false; |
|
448 |
|
449 ItemList &cl = *clit->my_class, |
|
450 &al = *lai->my_class; |
|
451 |
|
452 bool is_leader = (lai == ai); |
|
453 bool singleton = false; |
|
454 |
|
455 if (is_leader) { |
|
456 ++lai; |
|
457 } |
|
458 |
|
459 cl.splice(cl.end(), al, ai); |
|
460 |
|
461 if (is_leader) { |
|
462 if (ai->size == 1) { |
|
463 classes.erase(ai->my_class); |
|
464 singleton = true; |
|
465 } |
|
466 else { |
|
467 lai->size = ai->size; |
|
468 lai->my_class = ai->my_class; |
|
469 } |
|
470 } |
|
471 if (!singleton) { |
|
472 for (IIter i = lai; i != al.end(); ++i) |
|
473 i->parent = lai; |
|
474 --lai->size; |
|
475 } |
|
476 |
|
477 ai->parent = clit; |
|
478 ++clit->size; |
|
479 |
|
480 return true; |
|
481 } |
|
482 |
|
483 |
|
484 /** |
|
485 * \brief Removes the given element from the structure. |
|
486 * |
|
487 * Removes the element from its component and if the component becomes |
|
488 * empty then removes that component from the component list. |
|
489 * |
|
490 * It is an error to remove an element which is not in the structure. |
|
491 */ |
|
492 void erase(const T &a) { |
|
493 |
|
494 IIter ma = m[a]; |
|
495 |
|
496 IIter la = _find(ma); |
|
497 if (la == ma) { |
|
498 if (ma -> size == 1){ |
|
499 classes.erase(ma->my_class); |
|
500 return; |
|
501 } |
|
502 ++la; |
|
503 la->size = ma->size; |
|
504 la->my_class = ma->my_class; |
|
505 } |
|
506 |
|
507 for (IIter i = la; i != la->my_class->end(); ++i) { |
|
508 i->parent = la; |
|
509 } |
|
510 |
|
511 la->size--; |
|
512 la->my_class->erase(ma); |
|
513 } |
|
514 |
|
515 /** |
|
516 * \brief Removes the component of the given element from the structure. |
|
517 * |
|
518 * Removes the component of the given element from the structure. |
|
519 * |
|
520 * It is an error to give an element which is not in the structure. |
|
521 */ |
|
522 |
|
523 void eraseClass(const T &a) { |
|
524 IIter ma = m[a]; |
|
525 classes.erase(_find(ma)->my_class); |
|
526 } |
|
527 |
|
528 |
|
529 class ClassIt { |
|
530 friend class UnionFindEnum; |
|
531 |
|
532 CcIter i; |
|
533 const ClassList *l; |
|
534 |
|
535 public: |
|
536 ClassIt(Invalid): l(0) {} |
|
537 ClassIt() {} |
|
538 ClassIt(UnionFindEnum const &ufe) { |
|
539 l = &ufe.classes; |
|
540 i = l->begin(); |
|
541 } |
|
542 |
|
543 operator const T& () const { |
|
544 ItemList const &ll = *i; |
|
545 return (ll.begin())->me; |
|
546 } |
|
547 bool operator == (ClassIt const &it) const { |
|
548 return (l==it.l && i==it.i) || (!valid() && !it.valid()); |
|
549 } |
|
550 bool operator != (ClassIt const &it) const { |
|
551 return !(*this == it); |
|
552 } |
|
553 bool operator < (ClassIt const &it) const { |
|
554 return (i < it.i); |
|
555 } |
|
556 |
|
557 bool operator==(Invalid) const { |
|
558 return !valid(); |
|
559 } |
|
560 bool operator!=(Invalid) const { |
|
561 return valid(); |
|
562 } |
|
563 |
|
564 ClassIt& operator++() { |
|
565 ++i; |
|
566 return *this; |
|
567 } |
|
568 |
|
569 // obsoleted: |
|
570 bool valid() const { return l!=0 && i!=l->end(); } |
|
571 }; |
|
572 |
|
573 /** |
|
574 * \brief Sets the iterator to point to the first component. |
|
575 * |
|
576 * Sets the iterator to point to the first component. |
|
577 * |
|
578 * With the \ref first, \ref valid and \ref next methods you can |
|
579 * iterate through the components. For example: |
|
580 * \code |
|
581 * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G); |
|
582 * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map); |
|
583 * UnionFindEnum<Graph::Node, Graph::NodeMap>::ClassIt iter; |
|
584 * for (U.first(iter); U.valid(iter); U.next(iter)) { |
|
585 * // iter is convertible to Graph::Node |
|
586 * cout << iter << endl; |
|
587 * } |
|
588 * \endcode |
|
589 * |
|
590 * \bug obsoleted, use the new LEMON iterator interface instead |
|
591 */ |
|
592 |
|
593 ClassIt& first(ClassIt& it) const { |
|
594 it = ClassIt(*this); |
|
595 return it; |
|
596 } |
|
597 |
|
598 /** |
|
599 * \brief Returns whether the iterator is valid. |
|
600 * |
|
601 * Returns whether the iterator is valid. |
|
602 * |
|
603 * With the \ref first, \ref valid and \ref next methods you can |
|
604 * iterate through the components. See the example here: \ref first. |
|
605 * |
|
606 * \bug obsoleted, use the new LEMON iterator interface instead |
|
607 */ |
|
608 |
|
609 bool valid(ClassIt const &it) const { |
|
610 return it.valid(); |
|
611 } |
|
612 |
|
613 /** |
|
614 * \brief Steps the iterator to the next component. |
|
615 * |
|
616 * Steps the iterator to the next component. |
|
617 * |
|
618 * With the \ref first, \ref valid and \ref next methods you can |
|
619 * iterate through the components. See the example here: \ref first. |
|
620 */ |
|
621 |
|
622 ClassIt& next(ClassIt& it) const { |
|
623 return ++it; |
|
624 } |
|
625 |
|
626 |
|
627 class ItemIt { |
|
628 friend class UnionFindEnum; |
|
629 |
|
630 IcIter i; |
|
631 const ItemList *l; |
|
632 public: |
|
633 ItemIt(Invalid): l(0) {} |
|
634 ItemIt() {} |
|
635 ItemIt(UnionFindEnum const &ufe, const T& a) { |
|
636 l = &ufe.classOf(a); |
|
637 i = l->begin(); |
|
638 } |
|
639 |
|
640 operator const T& () const { return i->me; } |
|
641 bool operator == (ItemIt const &it) const { |
|
642 return (l==it.l && i==it.i) || (!valid() && !it.valid()); |
|
643 } |
|
644 bool operator != (ItemIt const &it) const { |
|
645 return !(*this == it); |
|
646 } |
|
647 bool operator < (ItemIt const &it) const { |
|
648 return (i < it.i); |
|
649 } |
|
650 |
|
651 bool operator==(Invalid) const { |
|
652 return !valid(); |
|
653 } |
|
654 bool operator!=(Invalid) const { |
|
655 return valid(); |
|
656 } |
|
657 |
|
658 ItemIt& operator++() { |
|
659 ++i; |
|
660 return *this; |
|
661 } |
|
662 |
|
663 // obsoleted: |
|
664 bool valid() const { return l!=0 && i!=l->end(); } |
|
665 }; |
|
666 |
|
667 |
|
668 |
|
669 /** |
|
670 * \brief Sets the iterator to point to the first element of the component. |
|
671 * |
|
672 * \anchor first2 |
|
673 * Sets the iterator to point to the first element of the component. |
|
674 * |
|
675 * With the \ref first2 "first", \ref valid2 "valid" |
|
676 * and \ref next2 "next" methods you can |
|
677 * iterate through the elements of a component. For example |
|
678 * (iterating through the component of the node \e node): |
|
679 * \code |
|
680 * Graph::Node node = ...; |
|
681 * UnionFindEnum<Graph::Node, Graph::NodeMap>::MapType map(G); |
|
682 * UnionFindEnum<Graph::Node, Graph::NodeMap> U(map); |
|
683 * UnionFindEnum<Graph::Node, Graph::NodeMap>::ItemIt iiter; |
|
684 * for (U.first(iiter, node); U.valid(iiter); U.next(iiter)) { |
|
685 * // iiter is convertible to Graph::Node |
|
686 * cout << iiter << endl; |
|
687 * } |
|
688 * \endcode |
|
689 * |
|
690 * \bug obsoleted, use the new LEMON iterator interface instead |
|
691 */ |
|
692 |
|
693 ItemIt& first(ItemIt& it, const T& a) const { |
|
694 it = ItemIt(*this, a); |
|
695 return it; |
|
696 } |
|
697 |
|
698 /** |
|
699 * \brief Returns whether the iterator is valid. |
|
700 * |
|
701 * \anchor valid2 |
|
702 * Returns whether the iterator is valid. |
|
703 * |
|
704 * With the \ref first2 "first", \ref valid2 "valid" |
|
705 * and \ref next2 "next" methods you can |
|
706 * iterate through the elements of a component. |
|
707 * See the example here: \ref first2 "first". |
|
708 * |
|
709 * \bug obsoleted, use the new LEMON iterator interface instead |
|
710 */ |
|
711 |
|
712 bool valid(ItemIt const &it) const { |
|
713 return it.valid(); |
|
714 } |
|
715 |
|
716 /** |
|
717 * \brief Steps the iterator to the next component. |
|
718 * |
|
719 * \anchor next2 |
|
720 * Steps the iterator to the next component. |
|
721 * |
|
722 * With the \ref first2 "first", \ref valid2 "valid" |
|
723 * and \ref next2 "next" methods you can |
|
724 * iterate through the elements of a component. |
|
725 * See the example here: \ref first2 "first". |
|
726 * |
|
727 * \bug obsoleted, use the new LEMON iterator interface instead |
|
728 */ |
|
729 |
|
730 ItemIt& next(ItemIt& it) const { |
|
731 return ++it; |
|
732 } |
|
733 |
|
734 }; |
|
735 |
|
736 |
|
737 //! @} |
579 //! @} |
738 |
580 |
739 } //namespace lemon |
581 } //namespace lemon |
740 |
582 |
741 #endif //LEMON_UNION_FIND_H |
583 #endif //LEMON_UNION_FIND_H |