36 |
36 |
37 /// \ingroup auxdat |
37 /// \ingroup auxdat |
38 /// |
38 /// |
39 /// \brief A \e Union-Find data structure implementation |
39 /// \brief A \e Union-Find data structure implementation |
40 /// |
40 /// |
41 /// The class implements the \e Union-Find data structure. |
41 /// The class implements the \e Union-Find data structure. |
42 /// The union operation uses rank heuristic, while |
42 /// The union operation uses rank heuristic, while |
43 /// the find operation uses path compression. |
43 /// the find operation uses path compression. |
44 /// This is a very simple but efficient implementation, providing |
44 /// This is a very simple but efficient implementation, providing |
45 /// only four methods: join (union), find, insert and size. |
45 /// only four methods: join (union), find, insert and size. |
46 /// For more features see the \ref UnionFindEnum class. |
46 /// For more features see the \ref UnionFindEnum class. |
47 /// |
47 /// |
48 /// It is primarily used in Kruskal algorithm for finding minimal |
48 /// It is primarily used in Kruskal algorithm for finding minimal |
49 /// cost spanning tree in a graph. |
49 /// cost spanning tree in a graph. |
50 /// \sa kruskal() |
50 /// \sa kruskal() |
51 /// |
51 /// |
52 /// \pre You need to add all the elements by the \ref insert() |
52 /// \pre You need to add all the elements by the \ref insert() |
53 /// method. |
53 /// method. |
54 template <typename _ItemIntMap> |
54 template <typename _ItemIntMap> |
55 class UnionFind { |
55 class UnionFind { |
56 public: |
56 public: |
57 |
57 |
58 typedef _ItemIntMap ItemIntMap; |
58 typedef _ItemIntMap ItemIntMap; |
121 return n; |
121 return n; |
122 } |
122 } |
123 |
123 |
124 /// \brief Joining the components of element \e a and element \e b. |
124 /// \brief Joining the components of element \e a and element \e b. |
125 /// |
125 /// |
126 /// This is the \e union operation of the Union-Find structure. |
126 /// This is the \e union operation of the Union-Find structure. |
127 /// Joins the component of element \e a and component of |
127 /// Joins the component of element \e a and component of |
128 /// element \e b. If \e a and \e b are in the same component then |
128 /// element \e b. If \e a and \e b are in the same component then |
129 /// it returns false otherwise it returns true. |
129 /// it returns false otherwise it returns true. |
130 bool join(const Item& a, const Item& b) { |
130 bool join(const Item& a, const Item& b) { |
131 int ka = repIndex(index[a]); |
131 int ka = repIndex(index[a]); |
132 int kb = repIndex(index[b]); |
132 int kb = repIndex(index[b]); |
133 |
133 |
134 if ( ka == kb ) |
134 if ( ka == kb ) |
135 return false; |
135 return false; |
136 |
136 |
137 if (items[ka] < items[kb]) { |
137 if (items[ka] < items[kb]) { |
138 items[ka] += items[kb]; |
138 items[ka] += items[kb]; |
139 items[kb] = ka; |
139 items[kb] = ka; |
140 } else { |
140 } else { |
141 items[kb] += items[ka]; |
141 items[kb] += items[ka]; |
142 items[ka] = kb; |
142 items[ka] = kb; |
143 } |
143 } |
144 return true; |
144 return true; |
145 } |
145 } |
146 |
146 |
147 /// \brief Returns the size of the component of element \e a. |
147 /// \brief Returns the size of the component of element \e a. |
200 struct ClassT { |
200 struct ClassT { |
201 int size; |
201 int size; |
202 int firstItem; |
202 int firstItem; |
203 int next, prev; |
203 int next, prev; |
204 }; |
204 }; |
205 |
205 |
206 std::vector<ClassT> classes; |
206 std::vector<ClassT> classes; |
207 int firstClass, firstFreeClass; |
207 int firstClass, firstFreeClass; |
208 |
208 |
209 int newClass() { |
209 int newClass() { |
210 if (firstFreeClass == -1) { |
210 if (firstFreeClass == -1) { |
211 int cdx = classes.size(); |
211 int cdx = classes.size(); |
212 classes.push_back(ClassT()); |
212 classes.push_back(ClassT()); |
213 return cdx; |
213 return cdx; |
214 } else { |
214 } else { |
215 int cdx = firstFreeClass; |
215 int cdx = firstFreeClass; |
216 firstFreeClass = classes[firstFreeClass].next; |
216 firstFreeClass = classes[firstFreeClass].next; |
217 return cdx; |
217 return cdx; |
218 } |
218 } |
219 } |
219 } |
220 |
220 |
221 int newItem() { |
221 int newItem() { |
222 if (firstFreeItem == -1) { |
222 if (firstFreeItem == -1) { |
223 int idx = items.size(); |
223 int idx = items.size(); |
224 items.push_back(ItemT()); |
224 items.push_back(ItemT()); |
225 return idx; |
225 return idx; |
226 } else { |
226 } else { |
227 int idx = firstFreeItem; |
227 int idx = firstFreeItem; |
228 firstFreeItem = items[firstFreeItem].next; |
228 firstFreeItem = items[firstFreeItem].next; |
229 return idx; |
229 return idx; |
230 } |
230 } |
231 } |
231 } |
232 |
232 |
233 |
233 |
234 bool rep(int idx) const { |
234 bool rep(int idx) const { |
265 } |
265 } |
266 |
266 |
267 void unlaceItem(int idx) { |
267 void unlaceItem(int idx) { |
268 items[items[idx].prev].next = items[idx].next; |
268 items[items[idx].prev].next = items[idx].next; |
269 items[items[idx].next].prev = items[idx].prev; |
269 items[items[idx].next].prev = items[idx].prev; |
270 |
270 |
271 items[idx].next = firstFreeItem; |
271 items[idx].next = firstFreeItem; |
272 firstFreeItem = idx; |
272 firstFreeItem = idx; |
273 } |
273 } |
274 |
274 |
275 void spliceItems(int ak, int bk) { |
275 void spliceItems(int ak, int bk) { |
276 items[items[ak].prev].next = bk; |
276 items[items[ak].prev].next = bk; |
277 items[items[bk].prev].next = ak; |
277 items[items[bk].prev].next = ak; |
278 int tmp = items[ak].prev; |
278 int tmp = items[ak].prev; |
279 items[ak].prev = items[bk].prev; |
279 items[ak].prev = items[bk].prev; |
280 items[bk].prev = tmp; |
280 items[bk].prev = tmp; |
281 |
281 |
282 } |
282 } |
283 |
283 |
284 void laceClass(int cls) { |
284 void laceClass(int cls) { |
285 if (firstClass != -1) { |
285 if (firstClass != -1) { |
286 classes[firstClass].prev = cls; |
286 classes[firstClass].prev = cls; |
287 } |
287 } |
288 classes[cls].next = firstClass; |
288 classes[cls].next = firstClass; |
289 classes[cls].prev = -1; |
289 classes[cls].prev = -1; |
290 firstClass = cls; |
290 firstClass = cls; |
291 } |
291 } |
292 |
292 |
293 void unlaceClass(int cls) { |
293 void unlaceClass(int cls) { |
294 if (classes[cls].prev != -1) { |
294 if (classes[cls].prev != -1) { |
295 classes[classes[cls].prev].next = classes[cls].next; |
295 classes[classes[cls].prev].next = classes[cls].next; |
296 } else { |
296 } else { |
297 firstClass = classes[cls].next; |
297 firstClass = classes[cls].next; |
298 } |
298 } |
299 if (classes[cls].next != -1) { |
299 if (classes[cls].next != -1) { |
300 classes[classes[cls].next].prev = classes[cls].prev; |
300 classes[classes[cls].next].prev = classes[cls].prev; |
301 } |
301 } |
302 |
302 |
303 classes[cls].next = firstFreeClass; |
303 classes[cls].next = firstFreeClass; |
304 firstFreeClass = cls; |
304 firstFreeClass = cls; |
305 } |
305 } |
306 |
306 |
307 public: |
307 public: |
308 |
308 |
309 UnionFindEnum(ItemIntMap& _index) |
309 UnionFindEnum(ItemIntMap& _index) |
310 : index(_index), items(), firstFreeItem(-1), |
310 : index(_index), items(), firstFreeItem(-1), |
311 firstClass(-1), firstFreeClass(-1) {} |
311 firstClass(-1), firstFreeClass(-1) {} |
312 |
312 |
313 /// \brief Inserts the given element into a new component. |
313 /// \brief Inserts the given element into a new component. |
314 /// |
314 /// |
315 /// This method creates a new component consisting only of the |
315 /// This method creates a new component consisting only of the |
316 /// given element. |
316 /// given element. |
317 /// |
317 /// |
370 return ~(items[repIndex(index[item])].parent); |
370 return ~(items[repIndex(index[item])].parent); |
371 } |
371 } |
372 |
372 |
373 /// \brief Joining the component of element \e a and element \e b. |
373 /// \brief Joining the component of element \e a and element \e b. |
374 /// |
374 /// |
375 /// This is the \e union operation of the Union-Find structure. |
375 /// This is the \e union operation of the Union-Find structure. |
376 /// Joins the component of element \e a and component of |
376 /// Joins the component of element \e a and component of |
377 /// element \e b. If \e a and \e b are in the same component then |
377 /// element \e b. If \e a and \e b are in the same component then |
378 /// returns -1 else returns the remaining class. |
378 /// returns -1 else returns the remaining class. |
379 int join(const Item& a, const Item& b) { |
379 int join(const Item& a, const Item& b) { |
380 |
380 |
381 int ak = repIndex(index[a]); |
381 int ak = repIndex(index[a]); |
382 int bk = repIndex(index[b]); |
382 int bk = repIndex(index[b]); |
383 |
383 |
384 if (ak == bk) { |
384 if (ak == bk) { |
385 return -1; |
385 return -1; |
386 } |
386 } |
387 |
387 |
388 int acx = ~(items[ak].parent); |
388 int acx = ~(items[ak].parent); |
389 int bcx = ~(items[bk].parent); |
389 int bcx = ~(items[bk].parent); |
390 |
390 |
391 int rcx; |
391 int rcx; |
392 |
392 |
393 if (classes[acx].size > classes[bcx].size) { |
393 if (classes[acx].size > classes[bcx].size) { |
394 classes[acx].size += classes[bcx].size; |
394 classes[acx].size += classes[bcx].size; |
395 items[bk].parent = ak; |
395 items[bk].parent = ak; |
396 unlaceClass(bcx); |
396 unlaceClass(bcx); |
397 rcx = acx; |
397 rcx = acx; |
398 } else { |
398 } else { |
399 classes[bcx].size += classes[acx].size; |
399 classes[bcx].size += classes[acx].size; |
400 items[ak].parent = bk; |
400 items[ak].parent = bk; |
401 unlaceClass(acx); |
401 unlaceClass(acx); |
402 rcx = bcx; |
402 rcx = bcx; |
403 } |
403 } |
404 spliceItems(ak, bk); |
404 spliceItems(ak, bk); |
405 |
405 |
406 return rcx; |
406 return rcx; |
407 } |
407 } |
411 /// Returns the size of the class. |
411 /// Returns the size of the class. |
412 int size(int cls) const { |
412 int size(int cls) const { |
413 return classes[cls].size; |
413 return classes[cls].size; |
414 } |
414 } |
415 |
415 |
416 /// \brief Splits up the component. |
416 /// \brief Splits up the component. |
417 /// |
417 /// |
418 /// Splitting the component into singleton components (component |
418 /// Splitting the component into singleton components (component |
419 /// of size one). |
419 /// of size one). |
420 void split(int cls) { |
420 void split(int cls) { |
421 int fdx = classes[cls].firstItem; |
421 int fdx = classes[cls].firstItem; |
422 int idx = items[fdx].next; |
422 int idx = items[fdx].next; |
423 while (idx != fdx) { |
423 while (idx != fdx) { |
424 int next = items[idx].next; |
424 int next = items[idx].next; |
425 |
425 |
426 singletonItem(idx); |
426 singletonItem(idx); |
427 |
427 |
428 int cdx = newClass(); |
428 int cdx = newClass(); |
429 items[idx].parent = ~cdx; |
429 items[idx].parent = ~cdx; |
430 |
430 |
431 laceClass(cdx); |
431 laceClass(cdx); |
432 classes[cdx].size = 1; |
432 classes[cdx].size = 1; |
433 classes[cdx].firstItem = idx; |
433 classes[cdx].firstItem = idx; |
434 |
434 |
435 idx = next; |
435 idx = next; |
436 } |
436 } |
437 |
437 |
438 items[idx].prev = idx; |
438 items[idx].prev = idx; |
439 items[idx].next = idx; |
439 items[idx].next = idx; |
440 |
440 |
441 classes[~(items[idx].parent)].size = 1; |
441 classes[~(items[idx].parent)].size = 1; |
442 |
442 |
443 } |
443 } |
444 |
444 |
445 /// \brief Removes the given element from the structure. |
445 /// \brief Removes the given element from the structure. |
446 /// |
446 /// |
447 /// Removes the element from its component and if the component becomes |
447 /// Removes the element from its component and if the component becomes |
512 |
512 |
513 /// \brief Constructor to get invalid iterator |
513 /// \brief Constructor to get invalid iterator |
514 /// |
514 /// |
515 /// Constructor to get invalid iterator |
515 /// Constructor to get invalid iterator |
516 ClassIt(Invalid) : unionFind(0), cdx(-1) {} |
516 ClassIt(Invalid) : unionFind(0), cdx(-1) {} |
517 |
517 |
518 /// \brief Increment operator |
518 /// \brief Increment operator |
519 /// |
519 /// |
520 /// It steps to the next representant item. |
520 /// It steps to the next representant item. |
521 ClassIt& operator++() { |
521 ClassIt& operator++() { |
522 cdx = unionFind->classes[cdx].next; |
522 cdx = unionFind->classes[cdx].next; |
523 return *this; |
523 return *this; |
524 } |
524 } |
525 |
525 |
526 /// \brief Conversion operator |
526 /// \brief Conversion operator |
527 /// |
527 /// |
528 /// It converts the iterator to the current representant item. |
528 /// It converts the iterator to the current representant item. |
529 operator int() const { |
529 operator int() const { |
530 return cdx; |
530 return cdx; |
531 } |
531 } |
532 |
532 |
533 /// \brief Equality operator |
533 /// \brief Equality operator |
534 /// |
534 /// |
535 /// Equality operator |
535 /// Equality operator |
536 bool operator==(const ClassIt& i) { |
536 bool operator==(const ClassIt& i) { |
537 return i.cdx == cdx; |
537 return i.cdx == cdx; |
538 } |
538 } |
539 |
539 |
540 /// \brief Inequality operator |
540 /// \brief Inequality operator |
541 /// |
541 /// |
542 /// Inequality operator |
542 /// Inequality operator |
543 bool operator!=(const ClassIt& i) { |
543 bool operator!=(const ClassIt& i) { |
544 return i.cdx != cdx; |
544 return i.cdx != cdx; |
545 } |
545 } |
546 |
546 |
547 private: |
547 private: |
548 const UnionFindEnum* unionFind; |
548 const UnionFindEnum* unionFind; |
549 int cdx; |
549 int cdx; |
550 }; |
550 }; |
551 |
551 |
575 |
575 |
576 /// \brief Constructor to get invalid iterator |
576 /// \brief Constructor to get invalid iterator |
577 /// |
577 /// |
578 /// Constructor to get invalid iterator |
578 /// Constructor to get invalid iterator |
579 ItemIt(Invalid) : unionFind(0), idx(-1) {} |
579 ItemIt(Invalid) : unionFind(0), idx(-1) {} |
580 |
580 |
581 /// \brief Increment operator |
581 /// \brief Increment operator |
582 /// |
582 /// |
583 /// It steps to the next item in the class. |
583 /// It steps to the next item in the class. |
584 ItemIt& operator++() { |
584 ItemIt& operator++() { |
585 idx = unionFind->items[idx].next; |
585 idx = unionFind->items[idx].next; |
586 if (idx == fdx) idx = -1; |
586 if (idx == fdx) idx = -1; |
587 return *this; |
587 return *this; |
588 } |
588 } |
589 |
589 |
590 /// \brief Conversion operator |
590 /// \brief Conversion operator |
591 /// |
591 /// |
592 /// It converts the iterator to the current item. |
592 /// It converts the iterator to the current item. |
593 operator const Item&() const { |
593 operator const Item&() const { |
594 return unionFind->items[idx].item; |
594 return unionFind->items[idx].item; |
595 } |
595 } |
596 |
596 |
597 /// \brief Equality operator |
597 /// \brief Equality operator |
598 /// |
598 /// |
599 /// Equality operator |
599 /// Equality operator |
600 bool operator==(const ItemIt& i) { |
600 bool operator==(const ItemIt& i) { |
601 return i.idx == idx; |
601 return i.idx == idx; |
602 } |
602 } |
603 |
603 |
604 /// \brief Inequality operator |
604 /// \brief Inequality operator |
605 /// |
605 /// |
606 /// Inequality operator |
606 /// Inequality operator |
607 bool operator!=(const ItemIt& i) { |
607 bool operator!=(const ItemIt& i) { |
608 return i.idx != idx; |
608 return i.idx != idx; |
609 } |
609 } |
610 |
610 |
611 private: |
611 private: |
612 const UnionFindEnum* unionFind; |
612 const UnionFindEnum* unionFind; |
613 int idx, fdx; |
613 int idx, fdx; |
614 }; |
614 }; |
615 |
615 |
656 |
656 |
657 int firstClass, firstFreeClass; |
657 int firstClass, firstFreeClass; |
658 |
658 |
659 int newClass() { |
659 int newClass() { |
660 if (firstFreeClass != -1) { |
660 if (firstFreeClass != -1) { |
661 int cdx = firstFreeClass; |
661 int cdx = firstFreeClass; |
662 firstFreeClass = classes[cdx].next; |
662 firstFreeClass = classes[cdx].next; |
663 return cdx; |
663 return cdx; |
664 } else { |
664 } else { |
665 classes.push_back(ClassT()); |
665 classes.push_back(ClassT()); |
666 return classes.size() - 1; |
666 return classes.size() - 1; |
667 } |
667 } |
668 } |
668 } |
669 |
669 |
670 int newItem() { |
670 int newItem() { |
671 if (firstFreeItem != -1) { |
671 if (firstFreeItem != -1) { |
672 int idx = firstFreeItem; |
672 int idx = firstFreeItem; |
673 firstFreeItem = items[idx].next; |
673 firstFreeItem = items[idx].next; |
674 return idx; |
674 return idx; |
675 } else { |
675 } else { |
676 items.push_back(ItemT()); |
676 items.push_back(ItemT()); |
677 return items.size() - 1; |
677 return items.size() - 1; |
678 } |
678 } |
679 } |
679 } |
680 |
680 |
681 public: |
681 public: |
682 |
682 |
683 /// \brief Constructor |
683 /// \brief Constructor |
684 ExtendFindEnum(ItemIntMap& _index) |
684 ExtendFindEnum(ItemIntMap& _index) |
685 : index(_index), items(), firstFreeItem(-1), |
685 : index(_index), items(), firstFreeItem(-1), |
686 classes(), firstClass(-1), firstFreeClass(-1) {} |
686 classes(), firstClass(-1), firstFreeClass(-1) {} |
687 |
687 |
688 /// \brief Inserts the given element into a new component. |
688 /// \brief Inserts the given element into a new component. |
689 /// |
689 /// |
690 /// This method creates a new component consisting only of the |
690 /// This method creates a new component consisting only of the |
691 /// given element. |
691 /// given element. |
692 int insert(const Item& item) { |
692 int insert(const Item& item) { |
693 int cdx = newClass(); |
693 int cdx = newClass(); |
694 classes[cdx].prev = -1; |
694 classes[cdx].prev = -1; |
695 classes[cdx].next = firstClass; |
695 classes[cdx].next = firstClass; |
696 if (firstClass != -1) { |
696 if (firstClass != -1) { |
697 classes[firstClass].prev = cdx; |
697 classes[firstClass].prev = cdx; |
698 } |
698 } |
699 firstClass = cdx; |
699 firstClass = cdx; |
700 |
700 |
701 int idx = newItem(); |
701 int idx = newItem(); |
702 items[idx].item = item; |
702 items[idx].item = item; |
703 items[idx].cls = cdx; |
703 items[idx].cls = cdx; |
704 items[idx].prev = idx; |
704 items[idx].prev = idx; |
705 items[idx].next = idx; |
705 items[idx].next = idx; |
706 |
706 |
707 classes[cdx].firstItem = idx; |
707 classes[cdx].firstItem = idx; |
708 |
708 |
709 index.set(item, idx); |
709 index.set(item, idx); |
710 |
710 |
711 return cdx; |
711 return cdx; |
712 } |
712 } |
713 |
713 |
714 /// \brief Inserts the given element into the given component. |
714 /// \brief Inserts the given element into the given component. |
715 /// |
715 /// |
748 /// |
748 /// |
749 /// Gives back a representant item of the component. |
749 /// Gives back a representant item of the component. |
750 Item item(int cls) const { |
750 Item item(int cls) const { |
751 return items[classes[cls].firstItem].item; |
751 return items[classes[cls].firstItem].item; |
752 } |
752 } |
753 |
753 |
754 /// \brief Removes the given element from the structure. |
754 /// \brief Removes the given element from the structure. |
755 /// |
755 /// |
756 /// Removes the element from its component and if the component becomes |
756 /// Removes the element from its component and if the component becomes |
757 /// empty then removes that component from the component list. |
757 /// empty then removes that component from the component list. |
758 /// |
758 /// |
759 /// \warning It is an error to remove an element which is not in |
759 /// \warning It is an error to remove an element which is not in |
760 /// the structure. |
760 /// the structure. |
761 void erase(const Item &item) { |
761 void erase(const Item &item) { |
762 int idx = index[item]; |
762 int idx = index[item]; |
763 int cdx = items[idx].cls; |
763 int cdx = items[idx].cls; |
764 |
764 |
765 if (idx == items[idx].next) { |
765 if (idx == items[idx].next) { |
766 if (classes[cdx].prev != -1) { |
766 if (classes[cdx].prev != -1) { |
767 classes[classes[cdx].prev].next = classes[cdx].next; |
767 classes[classes[cdx].prev].next = classes[cdx].next; |
768 } else { |
768 } else { |
769 firstClass = classes[cdx].next; |
769 firstClass = classes[cdx].next; |
770 } |
770 } |
771 if (classes[cdx].next != -1) { |
771 if (classes[cdx].next != -1) { |
772 classes[classes[cdx].next].prev = classes[cdx].prev; |
772 classes[classes[cdx].next].prev = classes[cdx].prev; |
773 } |
773 } |
774 classes[cdx].next = firstFreeClass; |
774 classes[cdx].next = firstFreeClass; |
775 firstFreeClass = cdx; |
775 firstFreeClass = cdx; |
776 } else { |
776 } else { |
777 classes[cdx].firstItem = items[idx].next; |
777 classes[cdx].firstItem = items[idx].next; |
778 items[items[idx].next].prev = items[idx].prev; |
778 items[items[idx].next].prev = items[idx].prev; |
779 items[items[idx].prev].next = items[idx].next; |
779 items[items[idx].prev].next = items[idx].next; |
780 } |
780 } |
781 items[idx].next = firstFreeItem; |
781 items[idx].next = firstFreeItem; |
782 firstFreeItem = idx; |
782 firstFreeItem = idx; |
783 |
783 |
784 } |
784 } |
785 |
785 |
786 |
786 |
787 /// \brief Removes the component of the given element from the structure. |
787 /// \brief Removes the component of the given element from the structure. |
788 /// |
788 /// |
789 /// Removes the component of the given element from the structure. |
789 /// Removes the component of the given element from the structure. |
790 /// |
790 /// |
791 /// \warning It is an error to give an element which is not in the |
791 /// \warning It is an error to give an element which is not in the |
822 |
822 |
823 /// \brief Constructor to get invalid iterator |
823 /// \brief Constructor to get invalid iterator |
824 /// |
824 /// |
825 /// Constructor to get invalid iterator |
825 /// Constructor to get invalid iterator |
826 ClassIt(Invalid) : extendFind(0), cdx(-1) {} |
826 ClassIt(Invalid) : extendFind(0), cdx(-1) {} |
827 |
827 |
828 /// \brief Increment operator |
828 /// \brief Increment operator |
829 /// |
829 /// |
830 /// It steps to the next representant item. |
830 /// It steps to the next representant item. |
831 ClassIt& operator++() { |
831 ClassIt& operator++() { |
832 cdx = extendFind->classes[cdx].next; |
832 cdx = extendFind->classes[cdx].next; |
833 return *this; |
833 return *this; |
834 } |
834 } |
835 |
835 |
836 /// \brief Conversion operator |
836 /// \brief Conversion operator |
837 /// |
837 /// |
838 /// It converts the iterator to the current class id. |
838 /// It converts the iterator to the current class id. |
839 operator int() const { |
839 operator int() const { |
840 return cdx; |
840 return cdx; |
841 } |
841 } |
842 |
842 |
843 /// \brief Equality operator |
843 /// \brief Equality operator |
844 /// |
844 /// |
845 /// Equality operator |
845 /// Equality operator |
846 bool operator==(const ClassIt& i) { |
846 bool operator==(const ClassIt& i) { |
847 return i.cdx == cdx; |
847 return i.cdx == cdx; |
848 } |
848 } |
849 |
849 |
850 /// \brief Inequality operator |
850 /// \brief Inequality operator |
851 /// |
851 /// |
852 /// Inequality operator |
852 /// Inequality operator |
853 bool operator!=(const ClassIt& i) { |
853 bool operator!=(const ClassIt& i) { |
854 return i.cdx != cdx; |
854 return i.cdx != cdx; |
855 } |
855 } |
856 |
856 |
857 private: |
857 private: |
858 const ExtendFindEnum* extendFind; |
858 const ExtendFindEnum* extendFind; |
859 int cdx; |
859 int cdx; |
860 }; |
860 }; |
861 |
861 |
885 |
885 |
886 /// \brief Constructor to get invalid iterator |
886 /// \brief Constructor to get invalid iterator |
887 /// |
887 /// |
888 /// Constructor to get invalid iterator |
888 /// Constructor to get invalid iterator |
889 ItemIt(Invalid) : extendFind(0), idx(-1) {} |
889 ItemIt(Invalid) : extendFind(0), idx(-1) {} |
890 |
890 |
891 /// \brief Increment operator |
891 /// \brief Increment operator |
892 /// |
892 /// |
893 /// It steps to the next item in the class. |
893 /// It steps to the next item in the class. |
894 ItemIt& operator++() { |
894 ItemIt& operator++() { |
895 idx = extendFind->items[idx].next; |
895 idx = extendFind->items[idx].next; |
896 if (fdx == idx) idx = -1; |
896 if (fdx == idx) idx = -1; |
897 return *this; |
897 return *this; |
898 } |
898 } |
899 |
899 |
900 /// \brief Conversion operator |
900 /// \brief Conversion operator |
901 /// |
901 /// |
902 /// It converts the iterator to the current item. |
902 /// It converts the iterator to the current item. |
903 operator const Item&() const { |
903 operator const Item&() const { |
904 return extendFind->items[idx].item; |
904 return extendFind->items[idx].item; |
905 } |
905 } |
906 |
906 |
907 /// \brief Equality operator |
907 /// \brief Equality operator |
908 /// |
908 /// |
909 /// Equality operator |
909 /// Equality operator |
910 bool operator==(const ItemIt& i) { |
910 bool operator==(const ItemIt& i) { |
911 return i.idx == idx; |
911 return i.idx == idx; |
912 } |
912 } |
913 |
913 |
914 /// \brief Inequality operator |
914 /// \brief Inequality operator |
915 /// |
915 /// |
916 /// Inequality operator |
916 /// Inequality operator |
917 bool operator!=(const ItemIt& i) { |
917 bool operator!=(const ItemIt& i) { |
918 return i.idx != idx; |
918 return i.idx != idx; |
919 } |
919 } |
920 |
920 |
921 private: |
921 private: |
922 const ExtendFindEnum* extendFind; |
922 const ExtendFindEnum* extendFind; |
923 int idx, fdx; |
923 int idx, fdx; |
924 }; |
924 }; |
925 |
925 |
1130 |
1130 |
1131 void split(int id, int jd) { |
1131 void split(int id, int jd) { |
1132 int kd = nodes[id].parent; |
1132 int kd = nodes[id].parent; |
1133 nodes[kd].right = nodes[id].prev; |
1133 nodes[kd].right = nodes[id].prev; |
1134 nodes[nodes[id].prev].next = -1; |
1134 nodes[nodes[id].prev].next = -1; |
1135 |
1135 |
1136 nodes[jd].left = id; |
1136 nodes[jd].left = id; |
1137 nodes[id].prev = -1; |
1137 nodes[id].prev = -1; |
1138 int num = 0; |
1138 int num = 0; |
1139 while (id != -1) { |
1139 while (id != -1) { |
1140 nodes[id].parent = jd; |
1140 nodes[id].parent = jd; |
1141 nodes[jd].right = id; |
1141 nodes[jd].right = id; |
1142 id = nodes[id].next; |
1142 id = nodes[id].next; |
1143 ++num; |
1143 ++num; |
1144 } |
1144 } |
1145 nodes[kd].size -= num; |
1145 nodes[kd].size -= num; |
1146 nodes[jd].size = num; |
1146 nodes[jd].size = num; |
1147 } |
1147 } |
1148 |
1148 |
1149 void pushLeft(int id, int jd) { |
1149 void pushLeft(int id, int jd) { |
1163 } |
1163 } |
1164 |
1164 |
1165 void repairLeft(int id) { |
1165 void repairLeft(int id) { |
1166 int jd = ~(classes[id].parent); |
1166 int jd = ~(classes[id].parent); |
1167 while (nodes[jd].left != -1) { |
1167 while (nodes[jd].left != -1) { |
1168 int kd = nodes[jd].left; |
1168 int kd = nodes[jd].left; |
1169 if (nodes[jd].size == 1) { |
1169 if (nodes[jd].size == 1) { |
1170 if (nodes[jd].parent < 0) { |
1170 if (nodes[jd].parent < 0) { |
1171 classes[id].parent = ~kd; |
1171 classes[id].parent = ~kd; |
1172 classes[id].depth -= 1; |
1172 classes[id].depth -= 1; |
1173 nodes[kd].parent = ~id; |
1173 nodes[kd].parent = ~id; |
1174 deleteNode(jd); |
1174 deleteNode(jd); |
1175 jd = kd; |
1175 jd = kd; |
1176 } else { |
1176 } else { |
1177 int pd = nodes[jd].parent; |
1177 int pd = nodes[jd].parent; |
1178 if (nodes[nodes[jd].next].size < cmax) { |
1178 if (nodes[nodes[jd].next].size < cmax) { |
1179 pushLeft(nodes[jd].next, nodes[jd].left); |
1179 pushLeft(nodes[jd].next, nodes[jd].left); |
1180 if (less(nodes[jd].left, nodes[jd].next)) { |
1180 if (less(nodes[jd].left, nodes[jd].next)) { |
1181 nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio; |
1181 nodes[nodes[jd].next].prio = nodes[nodes[jd].left].prio; |
1182 nodes[nodes[jd].next].item = nodes[nodes[jd].left].item; |
1182 nodes[nodes[jd].next].item = nodes[nodes[jd].left].item; |
1183 } |
1183 } |
1184 popLeft(pd); |
1184 popLeft(pd); |
1185 deleteNode(jd); |
1185 deleteNode(jd); |
1186 jd = pd; |
1186 jd = pd; |
1187 } else { |
1187 } else { |
1188 int ld = nodes[nodes[jd].next].left; |
1188 int ld = nodes[nodes[jd].next].left; |
1189 popLeft(nodes[jd].next); |
1189 popLeft(nodes[jd].next); |
1190 pushRight(jd, ld); |
1190 pushRight(jd, ld); |
1191 if (less(ld, nodes[jd].left)) { |
1191 if (less(ld, nodes[jd].left)) { |
1192 nodes[jd].item = nodes[ld].item; |
1192 nodes[jd].item = nodes[ld].item; |
1193 nodes[jd].prio = nodes[jd].prio; |
1193 nodes[jd].prio = nodes[jd].prio; |
1194 } |
1194 } |
1195 if (nodes[nodes[jd].next].item == nodes[ld].item) { |
1195 if (nodes[nodes[jd].next].item == nodes[ld].item) { |
1196 setPrio(nodes[jd].next); |
1196 setPrio(nodes[jd].next); |
1197 } |
1197 } |
1198 jd = nodes[jd].left; |
1198 jd = nodes[jd].left; |
1199 } |
1199 } |
1200 } |
1200 } |
1201 } else { |
1201 } else { |
1202 jd = nodes[jd].left; |
1202 jd = nodes[jd].left; |
1203 } |
1203 } |
1204 } |
1204 } |
1205 } |
1205 } |
1206 |
1206 |
1207 void repairRight(int id) { |
1207 void repairRight(int id) { |
1208 int jd = ~(classes[id].parent); |
1208 int jd = ~(classes[id].parent); |
1209 while (nodes[jd].right != -1) { |
1209 while (nodes[jd].right != -1) { |
1210 int kd = nodes[jd].right; |
1210 int kd = nodes[jd].right; |
1211 if (nodes[jd].size == 1) { |
1211 if (nodes[jd].size == 1) { |
1212 if (nodes[jd].parent < 0) { |
1212 if (nodes[jd].parent < 0) { |
1213 classes[id].parent = ~kd; |
1213 classes[id].parent = ~kd; |
1214 classes[id].depth -= 1; |
1214 classes[id].depth -= 1; |
1215 nodes[kd].parent = ~id; |
1215 nodes[kd].parent = ~id; |
1216 deleteNode(jd); |
1216 deleteNode(jd); |
1217 jd = kd; |
1217 jd = kd; |
1218 } else { |
1218 } else { |
1219 int pd = nodes[jd].parent; |
1219 int pd = nodes[jd].parent; |
1220 if (nodes[nodes[jd].prev].size < cmax) { |
1220 if (nodes[nodes[jd].prev].size < cmax) { |
1221 pushRight(nodes[jd].prev, nodes[jd].right); |
1221 pushRight(nodes[jd].prev, nodes[jd].right); |
1222 if (less(nodes[jd].right, nodes[jd].prev)) { |
1222 if (less(nodes[jd].right, nodes[jd].prev)) { |
1223 nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio; |
1223 nodes[nodes[jd].prev].prio = nodes[nodes[jd].right].prio; |
1224 nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item; |
1224 nodes[nodes[jd].prev].item = nodes[nodes[jd].right].item; |
1225 } |
1225 } |
1226 popRight(pd); |
1226 popRight(pd); |
1227 deleteNode(jd); |
1227 deleteNode(jd); |
1228 jd = pd; |
1228 jd = pd; |
1229 } else { |
1229 } else { |
1230 int ld = nodes[nodes[jd].prev].right; |
1230 int ld = nodes[nodes[jd].prev].right; |
1231 popRight(nodes[jd].prev); |
1231 popRight(nodes[jd].prev); |
1232 pushLeft(jd, ld); |
1232 pushLeft(jd, ld); |
1233 if (less(ld, nodes[jd].right)) { |
1233 if (less(ld, nodes[jd].right)) { |
1234 nodes[jd].item = nodes[ld].item; |
1234 nodes[jd].item = nodes[ld].item; |
1235 nodes[jd].prio = nodes[jd].prio; |
1235 nodes[jd].prio = nodes[jd].prio; |
1236 } |
1236 } |
1237 if (nodes[nodes[jd].prev].item == nodes[ld].item) { |
1237 if (nodes[nodes[jd].prev].item == nodes[ld].item) { |
1238 setPrio(nodes[jd].prev); |
1238 setPrio(nodes[jd].prev); |
1239 } |
1239 } |
1240 jd = nodes[jd].right; |
1240 jd = nodes[jd].right; |
1241 } |
1241 } |
1242 } |
1242 } |
1243 } else { |
1243 } else { |
1244 jd = nodes[jd].right; |
1244 jd = nodes[jd].right; |
1245 } |
1245 } |
1246 } |
1246 } |
1247 } |
1247 } |
1248 |
1248 |
1249 |
1249 |
1250 bool less(int id, int jd) const { |
1250 bool less(int id, int jd) const { |
1274 return classes[cls].left == -1; |
1274 return classes[cls].left == -1; |
1275 } |
1275 } |
1276 |
1276 |
1277 /// \brief Constructs the union-find. |
1277 /// \brief Constructs the union-find. |
1278 /// |
1278 /// |
1279 /// Constructs the union-find. |
1279 /// Constructs the union-find. |
1280 /// \brief _index The index map of the union-find. The data |
1280 /// \brief _index The index map of the union-find. The data |
1281 /// structure uses internally for store references. |
1281 /// structure uses internally for store references. |
1282 HeapUnionFind(ItemIntMap& _index) |
1282 HeapUnionFind(ItemIntMap& _index) |
1283 : index(_index), first_class(-1), |
1283 : index(_index), first_class(-1), |
1284 first_free_class(-1), first_free_node(-1) {} |
1284 first_free_class(-1), first_free_node(-1) {} |
1285 |
1285 |
1286 /// \brief Insert a new node into a new component. |
1286 /// \brief Insert a new node into a new component. |
1287 /// |
1287 /// |
1288 /// Insert a new node into a new component. |
1288 /// Insert a new node into a new component. |
1289 /// \param item The item of the new node. |
1289 /// \param item The item of the new node. |
1301 nodes[id].left = -1; |
1301 nodes[id].left = -1; |
1302 nodes[id].right = -1; |
1302 nodes[id].right = -1; |
1303 |
1303 |
1304 nodes[id].item = item; |
1304 nodes[id].item = item; |
1305 index[item] = id; |
1305 index[item] = id; |
1306 |
1306 |
1307 int class_id = newClass(); |
1307 int class_id = newClass(); |
1308 classes[class_id].parent = ~id; |
1308 classes[class_id].parent = ~id; |
1309 classes[class_id].depth = 0; |
1309 classes[class_id].depth = 0; |
1310 |
1310 |
1311 classes[class_id].left = -1; |
1311 classes[class_id].left = -1; |
1312 classes[class_id].right = -1; |
1312 classes[class_id].right = -1; |
1313 |
1313 |
1314 if (first_class != -1) { |
1314 if (first_class != -1) { |
1315 classes[first_class].prev = class_id; |
1315 classes[first_class].prev = class_id; |
1316 } |
1316 } |
1317 classes[class_id].next = first_class; |
1317 classes[class_id].next = first_class; |
1318 classes[class_id].prev = -1; |
1318 classes[class_id].prev = -1; |
1319 first_class = class_id; |
1319 first_class = class_id; |
1320 |
1320 |
1321 nodes[id].parent = ~class_id; |
1321 nodes[id].parent = ~class_id; |
1322 |
1322 |
1323 return class_id; |
1323 return class_id; |
1324 } |
1324 } |
1325 |
1325 |
1326 /// \brief The class of the item. |
1326 /// \brief The class of the item. |
1327 /// |
1327 /// |
1468 } |
1468 } |
1469 nodes[~(classes[r].parent)].parent = ~l; |
1469 nodes[~(classes[r].parent)].parent = ~l; |
1470 classes[l].parent = classes[r].parent; |
1470 classes[l].parent = classes[r].parent; |
1471 classes[l].depth = classes[r].depth; |
1471 classes[l].depth = classes[r].depth; |
1472 } else { |
1472 } else { |
1473 if (classes[l].depth != 0 && |
1473 if (classes[l].depth != 0 && |
1474 nodes[~(classes[l].parent)].size + |
1474 nodes[~(classes[l].parent)].size + |
1475 nodes[~(classes[r].parent)].size <= cmax) { |
1475 nodes[~(classes[r].parent)].size <= cmax) { |
1476 splice(~(classes[l].parent), ~(classes[r].parent)); |
1476 splice(~(classes[l].parent), ~(classes[r].parent)); |
1477 deleteNode(~(classes[r].parent)); |
1477 deleteNode(~(classes[r].parent)); |
1478 if (less(~(classes[r].parent), ~(classes[l].parent))) { |
1478 if (less(~(classes[r].parent), ~(classes[l].parent))) { |
1479 nodes[~(classes[l].parent)].prio = |
1479 nodes[~(classes[l].parent)].prio = |
1480 nodes[~(classes[r].parent)].prio; |
1480 nodes[~(classes[r].parent)].prio; |
1481 nodes[~(classes[l].parent)].item = |
1481 nodes[~(classes[l].parent)].item = |
1482 nodes[~(classes[r].parent)].item; |
1482 nodes[~(classes[r].parent)].item; |
1483 } |
1483 } |
1484 } else { |
1484 } else { |
1485 int new_parent = newNode(); |
1485 int new_parent = newNode(); |
1486 nodes[new_parent].next = nodes[new_parent].prev = -1; |
1486 nodes[new_parent].next = nodes[new_parent].prev = -1; |
1487 push(new_parent, ~(classes[l].parent)); |
1487 push(new_parent, ~(classes[l].parent)); |
1488 pushRight(new_parent, ~(classes[r].parent)); |
1488 pushRight(new_parent, ~(classes[r].parent)); |
1489 setPrio(new_parent); |
1489 setPrio(new_parent); |
1490 |
1490 |
1491 classes[l].parent = ~new_parent; |
1491 classes[l].parent = ~new_parent; |
1492 classes[l].depth += 1; |
1492 classes[l].depth += 1; |
1493 nodes[new_parent].parent = ~l; |
1493 nodes[new_parent].parent = ~l; |
1494 } |
1494 } |
1495 } |
1495 } |
1540 } |
1540 } |
1541 |
1541 |
1542 classes[classes[id].right].next = first_class; |
1542 classes[classes[id].right].next = first_class; |
1543 classes[first_class].prev = classes[id].right; |
1543 classes[first_class].prev = classes[id].right; |
1544 first_class = classes[id].left; |
1544 first_class = classes[id].left; |
1545 |
1545 |
1546 if (classes[id].next != -1) { |
1546 if (classes[id].next != -1) { |
1547 classes[classes[id].next].prev = classes[id].prev; |
1547 classes[classes[id].next].prev = classes[id].prev; |
1548 } |
1548 } |
1549 classes[classes[id].prev].next = classes[id].next; |
1549 classes[classes[id].prev].next = classes[id].next; |
1550 |
1550 |
1551 deleteClass(id); |
1551 deleteClass(id); |
1552 } |
1552 } |
1553 |
1553 |
1554 { |
1554 { |
1555 for (int i = 1; i < int(cs.size()); ++i) { |
1555 for (int i = 1; i < int(cs.size()); ++i) { |
1556 int l = classes[cs[i]].depth; |
1556 int l = classes[cs[i]].depth; |
1557 while (nodes[nodes[l].parent].left == l) { |
1557 while (nodes[nodes[l].parent].left == l) { |
1558 l = nodes[l].parent; |
1558 l = nodes[l].parent; |
1559 } |
1559 } |
1560 int r = l; |
1560 int r = l; |
1561 while (nodes[l].parent >= 0) { |
1561 while (nodes[l].parent >= 0) { |
1562 l = nodes[l].parent; |
1562 l = nodes[l].parent; |
1563 int new_node = newNode(); |
1563 int new_node = newNode(); |
1564 |
1564 |
1565 nodes[new_node].prev = -1; |
1565 nodes[new_node].prev = -1; |
1710 /// |
1710 /// |
1711 /// It converts the iterator to the current item. |
1711 /// It converts the iterator to the current item. |
1712 operator const Item&() const { |
1712 operator const Item&() const { |
1713 return _huf->nodes[_id].item; |
1713 return _huf->nodes[_id].item; |
1714 } |
1714 } |
1715 |
1715 |
1716 /// \brief Equality operator |
1716 /// \brief Equality operator |
1717 /// |
1717 /// |
1718 /// Equality operator |
1718 /// Equality operator |
1719 bool operator==(const ItemIt& i) { |
1719 bool operator==(const ItemIt& i) { |
1720 return i._id == _id; |
1720 return i._id == _id; |
1721 } |
1721 } |
1722 |
1722 |
1723 /// \brief Inequality operator |
1723 /// \brief Inequality operator |
1724 /// |
1724 /// |
1725 /// Inequality operator |
1725 /// Inequality operator |
1726 bool operator!=(const ItemIt& i) { |
1726 bool operator!=(const ItemIt& i) { |
1727 return i._id != _id; |
1727 return i._id != _id; |
1728 } |
1728 } |
1729 |
1729 |
1730 /// \brief Equality operator |
1730 /// \brief Equality operator |
1731 /// |
1731 /// |
1732 /// Equality operator |
1732 /// Equality operator |
1733 bool operator==(Invalid) { |
1733 bool operator==(Invalid) { |
1734 return _id == _lid; |
1734 return _id == _lid; |
1735 } |
1735 } |
1736 |
1736 |
1737 /// \brief Inequality operator |
1737 /// \brief Inequality operator |
1738 /// |
1738 /// |
1739 /// Inequality operator |
1739 /// Inequality operator |
1740 bool operator!=(Invalid) { |
1740 bool operator!=(Invalid) { |
1741 return _id != _lid; |
1741 return _id != _lid; |
1742 } |
1742 } |
1743 |
1743 |
1744 }; |
1744 }; |
1745 |
1745 |
1746 /// \brief Class iterator |
1746 /// \brief Class iterator |
1747 /// |
1747 /// |
1748 /// The iterator stores |
1748 /// The iterator stores |
1749 class ClassIt { |
1749 class ClassIt { |
1750 private: |
1750 private: |
1751 |
1751 |
1752 const HeapUnionFind* _huf; |
1752 const HeapUnionFind* _huf; |
1753 int _id; |
1753 int _id; |
1754 |
1754 |
1755 public: |
1755 public: |
1756 |
1756 |
1757 ClassIt(const HeapUnionFind& huf) |
1757 ClassIt(const HeapUnionFind& huf) |
1758 : _huf(&huf), _id(huf.first_class) {} |
1758 : _huf(&huf), _id(huf.first_class) {} |
1759 |
1759 |
1760 ClassIt(const HeapUnionFind& huf, int cls) |
1760 ClassIt(const HeapUnionFind& huf, int cls) |
1761 : _huf(&huf), _id(huf.classes[cls].left) {} |
1761 : _huf(&huf), _id(huf.classes[cls].left) {} |
1762 |
1762 |
1763 ClassIt(Invalid) : _huf(0), _id(-1) {} |
1763 ClassIt(Invalid) : _huf(0), _id(-1) {} |
1764 |
1764 |
1765 const ClassIt& operator++() { |
1765 const ClassIt& operator++() { |
1766 _id = _huf->classes[_id].next; |
1766 _id = _huf->classes[_id].next; |
1767 return *this; |
1767 return *this; |
1768 } |
1768 } |
1769 |
1769 |
1770 /// \brief Equality operator |
1770 /// \brief Equality operator |
1771 /// |
1771 /// |
1772 /// Equality operator |
1772 /// Equality operator |
1773 bool operator==(const ClassIt& i) { |
1773 bool operator==(const ClassIt& i) { |
1774 return i._id == _id; |
1774 return i._id == _id; |
1775 } |
1775 } |
1776 |
1776 |
1777 /// \brief Inequality operator |
1777 /// \brief Inequality operator |
1778 /// |
1778 /// |
1779 /// Inequality operator |
1779 /// Inequality operator |
1780 bool operator!=(const ClassIt& i) { |
1780 bool operator!=(const ClassIt& i) { |
1781 return i._id != _id; |
1781 return i._id != _id; |
1782 } |
1782 } |
1783 |
1783 |
1784 operator int() const { |
1784 operator int() const { |
1785 return _id; |
1785 return _id; |
1786 } |
1786 } |
1787 |
1787 |
1788 }; |
1788 }; |
1789 |
1789 |
1790 }; |
1790 }; |
1791 |
1791 |
1792 //! @} |
1792 //! @} |