gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix clear() function in ExtendFindEnum (#335)
0 1 0
default
1 file changed with 1 insertions and 1 deletions:
↑ Collapse diff ↑
Ignore white space 8192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_UNION_FIND_H
20 20
#define LEMON_UNION_FIND_H
21 21

	
22 22
//!\ingroup auxdat
23 23
//!\file
24 24
//!\brief Union-Find data structures.
25 25
//!
26 26

	
27 27
#include <vector>
28 28
#include <list>
29 29
#include <utility>
30 30
#include <algorithm>
31 31
#include <functional>
32 32

	
33 33
#include <lemon/core.h>
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \ingroup auxdat
38 38
  ///
39 39
  /// \brief A \e Union-Find data structure implementation
40 40
  ///
41 41
  /// The class implements the \e Union-Find data structure.
42 42
  /// The union operation uses rank heuristic, while
43 43
  /// the find operation uses path compression.
44 44
  /// This is a very simple but efficient implementation, providing
45 45
  /// only four methods: join (union), find, insert and size.
46 46
  /// For more features, see the \ref UnionFindEnum class.
47 47
  ///
48 48
  /// It is primarily used in Kruskal algorithm for finding minimal
49 49
  /// cost spanning tree in a graph.
50 50
  /// \sa kruskal()
51 51
  ///
52 52
  /// \pre You need to add all the elements by the \ref insert()
53 53
  /// method.
54 54
  template <typename IM>
55 55
  class UnionFind {
56 56
  public:
57 57

	
58 58
    ///\e
59 59
    typedef IM ItemIntMap;
60 60
    ///\e
61 61
    typedef typename ItemIntMap::Key Item;
62 62

	
63 63
  private:
64 64
    // If the items vector stores negative value for an item then
65 65
    // that item is root item and it has -items[it] component size.
66 66
    // Else the items[it] contains the index of the parent.
67 67
    std::vector<int> items;
68 68
    ItemIntMap& index;
69 69

	
70 70
    bool rep(int idx) const {
71 71
      return items[idx] < 0;
72 72
    }
73 73

	
74 74
    int repIndex(int idx) const {
75 75
      int k = idx;
76 76
      while (!rep(k)) {
77 77
        k = items[k] ;
78 78
      }
79 79
      while (idx != k) {
80 80
        int next = items[idx];
81 81
        const_cast<int&>(items[idx]) = k;
82 82
        idx = next;
83 83
      }
84 84
      return k;
85 85
    }
86 86

	
87 87
  public:
88 88

	
89 89
    /// \brief Constructor
90 90
    ///
91 91
    /// Constructor of the UnionFind class. You should give an item to
92 92
    /// integer map which will be used from the data structure. If you
93 93
    /// modify directly this map that may cause segmentation fault,
94 94
    /// invalid data structure, or infinite loop when you use again
95 95
    /// the union-find.
96 96
    UnionFind(ItemIntMap& m) : index(m) {}
97 97

	
98 98
    /// \brief Returns the index of the element's component.
99 99
    ///
100 100
    /// The method returns the index of the element's component.
101 101
    /// This is an integer between zero and the number of inserted elements.
102 102
    ///
103 103
    int find(const Item& a) {
104 104
      return repIndex(index[a]);
105 105
    }
106 106

	
107 107
    /// \brief Clears the union-find data structure
108 108
    ///
109 109
    /// Erase each item from the data structure.
110 110
    void clear() {
111 111
      items.clear();
112 112
    }
113 113

	
114 114
    /// \brief Inserts a new element into the structure.
115 115
    ///
116 116
    /// This method inserts a new element into the data structure.
117 117
    ///
118 118
    /// The method returns the index of the new component.
119 119
    int insert(const Item& a) {
120 120
      int n = items.size();
121 121
      items.push_back(-1);
122 122
      index.set(a,n);
123 123
      return n;
124 124
    }
125 125

	
126 126
    /// \brief Joining the components of element \e a and element \e b.
127 127
    ///
128 128
    /// This is the \e union operation of the Union-Find structure.
129 129
    /// Joins the component of element \e a and component of
130 130
    /// element \e b. If \e a and \e b are in the same component then
131 131
    /// it returns false otherwise it returns true.
132 132
    bool join(const Item& a, const Item& b) {
133 133
      int ka = repIndex(index[a]);
134 134
      int kb = repIndex(index[b]);
135 135

	
136 136
      if ( ka == kb )
137 137
        return false;
138 138

	
139 139
      if (items[ka] < items[kb]) {
140 140
        items[ka] += items[kb];
141 141
        items[kb] = ka;
142 142
      } else {
143 143
        items[kb] += items[ka];
144 144
        items[ka] = kb;
145 145
      }
146 146
      return true;
147 147
    }
148 148

	
149 149
    /// \brief Returns the size of the component of element \e a.
150 150
    ///
151 151
    /// Returns the size of the component of element \e a.
152 152
    int size(const Item& a) {
153 153
      int k = repIndex(index[a]);
154 154
      return - items[k];
155 155
    }
156 156

	
157 157
  };
158 158

	
159 159
  /// \ingroup auxdat
160 160
  ///
161 161
  /// \brief A \e Union-Find data structure implementation which
162 162
  /// is able to enumerate the components.
163 163
  ///
164 164
  /// The class implements a \e Union-Find data structure
165 165
  /// which is able to enumerate the components and the items in
166 166
  /// a component. If you don't need this feature then perhaps it's
167 167
  /// better to use the \ref UnionFind class which is more efficient.
168 168
  ///
169 169
  /// The union operation uses rank heuristic, while
170 170
  /// the find operation uses path compression.
171 171
  ///
172 172
  /// \pre You need to add all the elements by the \ref insert()
173 173
  /// method.
174 174
  ///
175 175
  template <typename IM>
176 176
  class UnionFindEnum {
177 177
  public:
178 178

	
179 179
    ///\e
180 180
    typedef IM ItemIntMap;
181 181
    ///\e
182 182
    typedef typename ItemIntMap::Key Item;
183 183

	
184 184
  private:
185 185

	
186 186
    ItemIntMap& index;
187 187

	
188 188
    // If the parent stores negative value for an item then that item
189 189
    // is root item and it has ~(items[it].parent) component id.  Else
190 190
    // the items[it].parent contains the index of the parent.
191 191
    //
192 192
    // The \c next and \c prev provides the double-linked
193 193
    // cyclic list of one component's items.
194 194
    struct ItemT {
195 195
      int parent;
196 196
      Item item;
197 197

	
198 198
      int next, prev;
199 199
    };
200 200

	
201 201
    std::vector<ItemT> items;
202 202
    int firstFreeItem;
203 203

	
204 204
    struct ClassT {
205 205
      int size;
206 206
      int firstItem;
207 207
      int next, prev;
208 208
    };
209 209

	
210 210
    std::vector<ClassT> classes;
211 211
    int firstClass, firstFreeClass;
212 212

	
213 213
    int newClass() {
214 214
      if (firstFreeClass == -1) {
215 215
        int cdx = classes.size();
216 216
        classes.push_back(ClassT());
217 217
        return cdx;
218 218
      } else {
219 219
        int cdx = firstFreeClass;
220 220
        firstFreeClass = classes[firstFreeClass].next;
221 221
        return cdx;
222 222
      }
223 223
    }
224 224

	
225 225
    int newItem() {
226 226
      if (firstFreeItem == -1) {
227 227
        int idx = items.size();
228 228
        items.push_back(ItemT());
229 229
        return idx;
230 230
      } else {
231 231
        int idx = firstFreeItem;
232 232
        firstFreeItem = items[firstFreeItem].next;
233 233
        return idx;
234 234
      }
235 235
    }
236 236

	
237 237

	
238 238
    bool rep(int idx) const {
239 239
      return items[idx].parent < 0;
240 240
    }
241 241

	
242 242
    int repIndex(int idx) const {
243 243
      int k = idx;
244 244
      while (!rep(k)) {
245 245
        k = items[k].parent;
246 246
      }
247 247
      while (idx != k) {
248 248
        int next = items[idx].parent;
249 249
        const_cast<int&>(items[idx].parent) = k;
250 250
        idx = next;
251 251
      }
252 252
      return k;
253 253
    }
254 254

	
255 255
    int classIndex(int idx) const {
256 256
      return ~(items[repIndex(idx)].parent);
257 257
    }
258 258

	
259 259
    void singletonItem(int idx) {
260 260
      items[idx].next = idx;
261 261
      items[idx].prev = idx;
262 262
    }
263 263

	
264 264
    void laceItem(int idx, int rdx) {
265 265
      items[idx].prev = rdx;
266 266
      items[idx].next = items[rdx].next;
267 267
      items[items[rdx].next].prev = idx;
268 268
      items[rdx].next = idx;
269 269
    }
270 270

	
271 271
    void unlaceItem(int idx) {
272 272
      items[items[idx].prev].next = items[idx].next;
273 273
      items[items[idx].next].prev = items[idx].prev;
274 274

	
275 275
      items[idx].next = firstFreeItem;
276 276
      firstFreeItem = idx;
277 277
    }
278 278

	
279 279
    void spliceItems(int ak, int bk) {
280 280
      items[items[ak].prev].next = bk;
281 281
      items[items[bk].prev].next = ak;
282 282
      int tmp = items[ak].prev;
283 283
      items[ak].prev = items[bk].prev;
284 284
      items[bk].prev = tmp;
285 285

	
286 286
    }
287 287

	
288 288
    void laceClass(int cls) {
289 289
      if (firstClass != -1) {
290 290
        classes[firstClass].prev = cls;
291 291
      }
292 292
      classes[cls].next = firstClass;
293 293
      classes[cls].prev = -1;
294 294
      firstClass = cls;
295 295
    }
296 296

	
297 297
    void unlaceClass(int cls) {
298 298
      if (classes[cls].prev != -1) {
299 299
        classes[classes[cls].prev].next = classes[cls].next;
300 300
      } else {
301 301
        firstClass = classes[cls].next;
302 302
      }
303 303
      if (classes[cls].next != -1) {
304 304
        classes[classes[cls].next].prev = classes[cls].prev;
305 305
      }
306 306

	
307 307
      classes[cls].next = firstFreeClass;
308 308
      firstFreeClass = cls;
309 309
    }
310 310

	
311 311
  public:
312 312

	
313 313
    UnionFindEnum(ItemIntMap& _index)
314 314
      : index(_index), items(), firstFreeItem(-1),
315 315
        firstClass(-1), firstFreeClass(-1) {}
316 316

	
317 317
    /// \brief Inserts the given element into a new component.
318 318
    ///
319 319
    /// This method creates a new component consisting only of the
320 320
    /// given element.
321 321
    ///
322 322
    int insert(const Item& item) {
323 323
      int idx = newItem();
324 324

	
325 325
      index.set(item, idx);
326 326

	
327 327
      singletonItem(idx);
328 328
      items[idx].item = item;
329 329

	
330 330
      int cdx = newClass();
331 331

	
332 332
      items[idx].parent = ~cdx;
333 333

	
334 334
      laceClass(cdx);
335 335
      classes[cdx].size = 1;
336 336
      classes[cdx].firstItem = idx;
337 337

	
338 338
      firstClass = cdx;
339 339

	
340 340
      return cdx;
341 341
    }
342 342

	
343 343
    /// \brief Inserts the given element into the component of the others.
344 344
    ///
345 345
    /// This methods inserts the element \e a into the component of the
346 346
    /// element \e comp.
347 347
    void insert(const Item& item, int cls) {
348 348
      int rdx = classes[cls].firstItem;
349 349
      int idx = newItem();
350 350

	
351 351
      index.set(item, idx);
352 352

	
353 353
      laceItem(idx, rdx);
354 354

	
355 355
      items[idx].item = item;
356 356
      items[idx].parent = rdx;
357 357

	
358 358
      ++classes[~(items[rdx].parent)].size;
359 359
    }
360 360

	
361 361
    /// \brief Clears the union-find data structure
362 362
    ///
363 363
    /// Erase each item from the data structure.
364 364
    void clear() {
365 365
      items.clear();
366 366
      firstClass = -1;
367 367
      firstFreeItem = -1;
368 368
    }
369 369

	
370 370
    /// \brief Finds the component of the given element.
371 371
    ///
372 372
    /// The method returns the component id of the given element.
373 373
    int find(const Item &item) const {
374 374
      return ~(items[repIndex(index[item])].parent);
375 375
    }
376 376

	
377 377
    /// \brief Joining the component of element \e a and element \e b.
378 378
    ///
379 379
    /// This is the \e union operation of the Union-Find structure.
380 380
    /// Joins the component of element \e a and component of
381 381
    /// element \e b. If \e a and \e b are in the same component then
382 382
    /// returns -1 else returns the remaining class.
383 383
    int join(const Item& a, const Item& b) {
384 384

	
385 385
      int ak = repIndex(index[a]);
386 386
      int bk = repIndex(index[b]);
387 387

	
388 388
      if (ak == bk) {
389 389
        return -1;
390 390
      }
391 391

	
392 392
      int acx = ~(items[ak].parent);
393 393
      int bcx = ~(items[bk].parent);
394 394

	
395 395
      int rcx;
396 396

	
397 397
      if (classes[acx].size > classes[bcx].size) {
398 398
        classes[acx].size += classes[bcx].size;
399 399
        items[bk].parent = ak;
400 400
        unlaceClass(bcx);
401 401
        rcx = acx;
402 402
      } else {
403 403
        classes[bcx].size += classes[acx].size;
404 404
        items[ak].parent = bk;
405 405
        unlaceClass(acx);
406 406
        rcx = bcx;
407 407
      }
408 408
      spliceItems(ak, bk);
409 409

	
410 410
      return rcx;
411 411
    }
412 412

	
413 413
    /// \brief Returns the size of the class.
414 414
    ///
415 415
    /// Returns the size of the class.
416 416
    int size(int cls) const {
417 417
      return classes[cls].size;
418 418
    }
419 419

	
420 420
    /// \brief Splits up the component.
421 421
    ///
422 422
    /// Splitting the component into singleton components (component
423 423
    /// of size one).
424 424
    void split(int cls) {
425 425
      int fdx = classes[cls].firstItem;
426 426
      int idx = items[fdx].next;
427 427
      while (idx != fdx) {
428 428
        int next = items[idx].next;
429 429

	
430 430
        singletonItem(idx);
431 431

	
432 432
        int cdx = newClass();
433 433
        items[idx].parent = ~cdx;
434 434

	
435 435
        laceClass(cdx);
436 436
        classes[cdx].size = 1;
437 437
        classes[cdx].firstItem = idx;
438 438

	
439 439
        idx = next;
440 440
      }
441 441

	
442 442
      items[idx].prev = idx;
443 443
      items[idx].next = idx;
444 444

	
445 445
      classes[~(items[idx].parent)].size = 1;
446 446

	
447 447
    }
448 448

	
449 449
    /// \brief Removes the given element from the structure.
450 450
    ///
451 451
    /// Removes the element from its component and if the component becomes
452 452
    /// empty then removes that component from the component list.
453 453
    ///
454 454
    /// \warning It is an error to remove an element which is not in
455 455
    /// the structure.
456 456
    /// \warning This running time of this operation is proportional to the
457 457
    /// number of the items in this class.
458 458
    void erase(const Item& item) {
459 459
      int idx = index[item];
460 460
      int fdx = items[idx].next;
461 461

	
462 462
      int cdx = classIndex(idx);
463 463
      if (idx == fdx) {
464 464
        unlaceClass(cdx);
465 465
        items[idx].next = firstFreeItem;
466 466
        firstFreeItem = idx;
467 467
        return;
468 468
      } else {
469 469
        classes[cdx].firstItem = fdx;
470 470
        --classes[cdx].size;
471 471
        items[fdx].parent = ~cdx;
472 472

	
473 473
        unlaceItem(idx);
474 474
        idx = items[fdx].next;
475 475
        while (idx != fdx) {
476 476
          items[idx].parent = fdx;
477 477
          idx = items[idx].next;
478 478
        }
479 479

	
480 480
      }
481 481

	
482 482
    }
483 483

	
484 484
    /// \brief Gives back a representant item of the component.
485 485
    ///
486 486
    /// Gives back a representant item of the component.
487 487
    Item item(int cls) const {
488 488
      return items[classes[cls].firstItem].item;
489 489
    }
490 490

	
491 491
    /// \brief Removes the component of the given element from the structure.
492 492
    ///
493 493
    /// Removes the component of the given element from the structure.
494 494
    ///
495 495
    /// \warning It is an error to give an element which is not in the
496 496
    /// structure.
497 497
    void eraseClass(int cls) {
498 498
      int fdx = classes[cls].firstItem;
499 499
      unlaceClass(cls);
500 500
      items[items[fdx].prev].next = firstFreeItem;
501 501
      firstFreeItem = fdx;
502 502
    }
503 503

	
504 504
    /// \brief LEMON style iterator for the representant items.
505 505
    ///
506 506
    /// ClassIt is a lemon style iterator for the components. It iterates
507 507
    /// on the ids of the classes.
508 508
    class ClassIt {
509 509
    public:
510 510
      /// \brief Constructor of the iterator
511 511
      ///
512 512
      /// Constructor of the iterator
513 513
      ClassIt(const UnionFindEnum& ufe) : unionFind(&ufe) {
514 514
        cdx = unionFind->firstClass;
515 515
      }
516 516

	
517 517
      /// \brief Constructor to get invalid iterator
518 518
      ///
519 519
      /// Constructor to get invalid iterator
520 520
      ClassIt(Invalid) : unionFind(0), cdx(-1) {}
521 521

	
522 522
      /// \brief Increment operator
523 523
      ///
524 524
      /// It steps to the next representant item.
525 525
      ClassIt& operator++() {
526 526
        cdx = unionFind->classes[cdx].next;
527 527
        return *this;
528 528
      }
529 529

	
530 530
      /// \brief Conversion operator
531 531
      ///
532 532
      /// It converts the iterator to the current representant item.
533 533
      operator int() const {
534 534
        return cdx;
535 535
      }
536 536

	
537 537
      /// \brief Equality operator
538 538
      ///
539 539
      /// Equality operator
540 540
      bool operator==(const ClassIt& i) {
541 541
        return i.cdx == cdx;
542 542
      }
543 543

	
544 544
      /// \brief Inequality operator
545 545
      ///
546 546
      /// Inequality operator
547 547
      bool operator!=(const ClassIt& i) {
548 548
        return i.cdx != cdx;
549 549
      }
550 550

	
551 551
    private:
552 552
      const UnionFindEnum* unionFind;
553 553
      int cdx;
554 554
    };
555 555

	
556 556
    /// \brief LEMON style iterator for the items of a component.
557 557
    ///
558 558
    /// ClassIt is a lemon style iterator for the components. It iterates
559 559
    /// on the items of a class. By example if you want to iterate on
560 560
    /// each items of each classes then you may write the next code.
561 561
    ///\code
562 562
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
563 563
    ///   std::cout << "Class: ";
564 564
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
565 565
    ///     std::cout << toString(iit) << ' ' << std::endl;
566 566
    ///   }
567 567
    ///   std::cout << std::endl;
568 568
    /// }
569 569
    ///\endcode
570 570
    class ItemIt {
571 571
    public:
572 572
      /// \brief Constructor of the iterator
573 573
      ///
574 574
      /// Constructor of the iterator. The iterator iterates
575 575
      /// on the class of the \c item.
576 576
      ItemIt(const UnionFindEnum& ufe, int cls) : unionFind(&ufe) {
577 577
        fdx = idx = unionFind->classes[cls].firstItem;
578 578
      }
579 579

	
580 580
      /// \brief Constructor to get invalid iterator
581 581
      ///
582 582
      /// Constructor to get invalid iterator
583 583
      ItemIt(Invalid) : unionFind(0), idx(-1) {}
584 584

	
585 585
      /// \brief Increment operator
586 586
      ///
587 587
      /// It steps to the next item in the class.
588 588
      ItemIt& operator++() {
589 589
        idx = unionFind->items[idx].next;
590 590
        if (idx == fdx) idx = -1;
591 591
        return *this;
592 592
      }
593 593

	
594 594
      /// \brief Conversion operator
595 595
      ///
596 596
      /// It converts the iterator to the current item.
597 597
      operator const Item&() const {
598 598
        return unionFind->items[idx].item;
599 599
      }
600 600

	
601 601
      /// \brief Equality operator
602 602
      ///
603 603
      /// Equality operator
604 604
      bool operator==(const ItemIt& i) {
605 605
        return i.idx == idx;
606 606
      }
607 607

	
608 608
      /// \brief Inequality operator
609 609
      ///
610 610
      /// Inequality operator
611 611
      bool operator!=(const ItemIt& i) {
612 612
        return i.idx != idx;
613 613
      }
614 614

	
615 615
    private:
616 616
      const UnionFindEnum* unionFind;
617 617
      int idx, fdx;
618 618
    };
619 619

	
620 620
  };
621 621

	
622 622
  /// \ingroup auxdat
623 623
  ///
624 624
  /// \brief A \e Extend-Find data structure implementation which
625 625
  /// is able to enumerate the components.
626 626
  ///
627 627
  /// The class implements an \e Extend-Find data structure which is
628 628
  /// able to enumerate the components and the items in a
629 629
  /// component. The data structure is a simplification of the
630 630
  /// Union-Find structure, and it does not allow to merge two components.
631 631
  ///
632 632
  /// \pre You need to add all the elements by the \ref insert()
633 633
  /// method.
634 634
  template <typename IM>
635 635
  class ExtendFindEnum {
636 636
  public:
637 637

	
638 638
    ///\e
639 639
    typedef IM ItemIntMap;
640 640
    ///\e
641 641
    typedef typename ItemIntMap::Key Item;
642 642

	
643 643
  private:
644 644

	
645 645
    ItemIntMap& index;
646 646

	
647 647
    struct ItemT {
648 648
      int cls;
649 649
      Item item;
650 650
      int next, prev;
651 651
    };
652 652

	
653 653
    std::vector<ItemT> items;
654 654
    int firstFreeItem;
655 655

	
656 656
    struct ClassT {
657 657
      int firstItem;
658 658
      int next, prev;
659 659
    };
660 660

	
661 661
    std::vector<ClassT> classes;
662 662

	
663 663
    int firstClass, firstFreeClass;
664 664

	
665 665
    int newClass() {
666 666
      if (firstFreeClass != -1) {
667 667
        int cdx = firstFreeClass;
668 668
        firstFreeClass = classes[cdx].next;
669 669
        return cdx;
670 670
      } else {
671 671
        classes.push_back(ClassT());
672 672
        return classes.size() - 1;
673 673
      }
674 674
    }
675 675

	
676 676
    int newItem() {
677 677
      if (firstFreeItem != -1) {
678 678
        int idx = firstFreeItem;
679 679
        firstFreeItem = items[idx].next;
680 680
        return idx;
681 681
      } else {
682 682
        items.push_back(ItemT());
683 683
        return items.size() - 1;
684 684
      }
685 685
    }
686 686

	
687 687
  public:
688 688

	
689 689
    /// \brief Constructor
690 690
    ExtendFindEnum(ItemIntMap& _index)
691 691
      : index(_index), items(), firstFreeItem(-1),
692 692
        classes(), firstClass(-1), firstFreeClass(-1) {}
693 693

	
694 694
    /// \brief Inserts the given element into a new component.
695 695
    ///
696 696
    /// This method creates a new component consisting only of the
697 697
    /// given element.
698 698
    int insert(const Item& item) {
699 699
      int cdx = newClass();
700 700
      classes[cdx].prev = -1;
701 701
      classes[cdx].next = firstClass;
702 702
      if (firstClass != -1) {
703 703
        classes[firstClass].prev = cdx;
704 704
      }
705 705
      firstClass = cdx;
706 706

	
707 707
      int idx = newItem();
708 708
      items[idx].item = item;
709 709
      items[idx].cls = cdx;
710 710
      items[idx].prev = idx;
711 711
      items[idx].next = idx;
712 712

	
713 713
      classes[cdx].firstItem = idx;
714 714

	
715 715
      index.set(item, idx);
716 716

	
717 717
      return cdx;
718 718
    }
719 719

	
720 720
    /// \brief Inserts the given element into the given component.
721 721
    ///
722 722
    /// This methods inserts the element \e item a into the \e cls class.
723 723
    void insert(const Item& item, int cls) {
724 724
      int idx = newItem();
725 725
      int rdx = classes[cls].firstItem;
726 726
      items[idx].item = item;
727 727
      items[idx].cls = cls;
728 728

	
729 729
      items[idx].prev = rdx;
730 730
      items[idx].next = items[rdx].next;
731 731
      items[items[rdx].next].prev = idx;
732 732
      items[rdx].next = idx;
733 733

	
734 734
      index.set(item, idx);
735 735
    }
736 736

	
737 737
    /// \brief Clears the union-find data structure
738 738
    ///
739 739
    /// Erase each item from the data structure.
740 740
    void clear() {
741 741
      items.clear();
742
      classes.clear;
742
      classes.clear();
743 743
      firstClass = firstFreeClass = firstFreeItem = -1;
744 744
    }
745 745

	
746 746
    /// \brief Gives back the class of the \e item.
747 747
    ///
748 748
    /// Gives back the class of the \e item.
749 749
    int find(const Item &item) const {
750 750
      return items[index[item]].cls;
751 751
    }
752 752

	
753 753
    /// \brief Gives back a representant item of the component.
754 754
    ///
755 755
    /// Gives back a representant item of the component.
756 756
    Item item(int cls) const {
757 757
      return items[classes[cls].firstItem].item;
758 758
    }
759 759

	
760 760
    /// \brief Removes the given element from the structure.
761 761
    ///
762 762
    /// Removes the element from its component and if the component becomes
763 763
    /// empty then removes that component from the component list.
764 764
    ///
765 765
    /// \warning It is an error to remove an element which is not in
766 766
    /// the structure.
767 767
    void erase(const Item &item) {
768 768
      int idx = index[item];
769 769
      int cdx = items[idx].cls;
770 770

	
771 771
      if (idx == items[idx].next) {
772 772
        if (classes[cdx].prev != -1) {
773 773
          classes[classes[cdx].prev].next = classes[cdx].next;
774 774
        } else {
775 775
          firstClass = classes[cdx].next;
776 776
        }
777 777
        if (classes[cdx].next != -1) {
778 778
          classes[classes[cdx].next].prev = classes[cdx].prev;
779 779
        }
780 780
        classes[cdx].next = firstFreeClass;
781 781
        firstFreeClass = cdx;
782 782
      } else {
783 783
        classes[cdx].firstItem = items[idx].next;
784 784
        items[items[idx].next].prev = items[idx].prev;
785 785
        items[items[idx].prev].next = items[idx].next;
786 786
      }
787 787
      items[idx].next = firstFreeItem;
788 788
      firstFreeItem = idx;
789 789

	
790 790
    }
791 791

	
792 792

	
793 793
    /// \brief Removes the component of the given element from the structure.
794 794
    ///
795 795
    /// Removes the component of the given element from the structure.
796 796
    ///
797 797
    /// \warning It is an error to give an element which is not in the
798 798
    /// structure.
799 799
    void eraseClass(int cdx) {
800 800
      int idx = classes[cdx].firstItem;
801 801
      items[items[idx].prev].next = firstFreeItem;
802 802
      firstFreeItem = idx;
803 803

	
804 804
      if (classes[cdx].prev != -1) {
805 805
        classes[classes[cdx].prev].next = classes[cdx].next;
806 806
      } else {
807 807
        firstClass = classes[cdx].next;
808 808
      }
809 809
      if (classes[cdx].next != -1) {
810 810
        classes[classes[cdx].next].prev = classes[cdx].prev;
811 811
      }
812 812
      classes[cdx].next = firstFreeClass;
813 813
      firstFreeClass = cdx;
814 814
    }
815 815

	
816 816
    /// \brief LEMON style iterator for the classes.
817 817
    ///
818 818
    /// ClassIt is a lemon style iterator for the components. It iterates
819 819
    /// on the ids of classes.
820 820
    class ClassIt {
821 821
    public:
822 822
      /// \brief Constructor of the iterator
823 823
      ///
824 824
      /// Constructor of the iterator
825 825
      ClassIt(const ExtendFindEnum& ufe) : extendFind(&ufe) {
826 826
        cdx = extendFind->firstClass;
827 827
      }
828 828

	
829 829
      /// \brief Constructor to get invalid iterator
830 830
      ///
831 831
      /// Constructor to get invalid iterator
832 832
      ClassIt(Invalid) : extendFind(0), cdx(-1) {}
833 833

	
834 834
      /// \brief Increment operator
835 835
      ///
836 836
      /// It steps to the next representant item.
837 837
      ClassIt& operator++() {
838 838
        cdx = extendFind->classes[cdx].next;
839 839
        return *this;
840 840
      }
841 841

	
842 842
      /// \brief Conversion operator
843 843
      ///
844 844
      /// It converts the iterator to the current class id.
845 845
      operator int() const {
846 846
        return cdx;
847 847
      }
848 848

	
849 849
      /// \brief Equality operator
850 850
      ///
851 851
      /// Equality operator
852 852
      bool operator==(const ClassIt& i) {
853 853
        return i.cdx == cdx;
854 854
      }
855 855

	
856 856
      /// \brief Inequality operator
857 857
      ///
858 858
      /// Inequality operator
859 859
      bool operator!=(const ClassIt& i) {
860 860
        return i.cdx != cdx;
861 861
      }
862 862

	
863 863
    private:
864 864
      const ExtendFindEnum* extendFind;
865 865
      int cdx;
866 866
    };
867 867

	
868 868
    /// \brief LEMON style iterator for the items of a component.
869 869
    ///
870 870
    /// ClassIt is a lemon style iterator for the components. It iterates
871 871
    /// on the items of a class. By example if you want to iterate on
872 872
    /// each items of each classes then you may write the next code.
873 873
    ///\code
874 874
    /// for (ClassIt cit(ufe); cit != INVALID; ++cit) {
875 875
    ///   std::cout << "Class: ";
876 876
    ///   for (ItemIt iit(ufe, cit); iit != INVALID; ++iit) {
877 877
    ///     std::cout << toString(iit) << ' ' << std::endl;
878 878
    ///   }
879 879
    ///   std::cout << std::endl;
880 880
    /// }
881 881
    ///\endcode
882 882
    class ItemIt {
883 883
    public:
884 884
      /// \brief Constructor of the iterator
885 885
      ///
886 886
      /// Constructor of the iterator. The iterator iterates
887 887
      /// on the class of the \c item.
888 888
      ItemIt(const ExtendFindEnum& ufe, int cls) : extendFind(&ufe) {
889 889
        fdx = idx = extendFind->classes[cls].firstItem;
890 890
      }
891 891

	
892 892
      /// \brief Constructor to get invalid iterator
893 893
      ///
894 894
      /// Constructor to get invalid iterator
895 895
      ItemIt(Invalid) : extendFind(0), idx(-1) {}
896 896

	
897 897
      /// \brief Increment operator
898 898
      ///
899 899
      /// It steps to the next item in the class.
900 900
      ItemIt& operator++() {
901 901
        idx = extendFind->items[idx].next;
902 902
        if (fdx == idx) idx = -1;
903 903
        return *this;
904 904
      }
905 905

	
906 906
      /// \brief Conversion operator
907 907
      ///
908 908
      /// It converts the iterator to the current item.
909 909
      operator const Item&() const {
910 910
        return extendFind->items[idx].item;
911 911
      }
912 912

	
913 913
      /// \brief Equality operator
914 914
      ///
915 915
      /// Equality operator
916 916
      bool operator==(const ItemIt& i) {
917 917
        return i.idx == idx;
918 918
      }
919 919

	
920 920
      /// \brief Inequality operator
921 921
      ///
922 922
      /// Inequality operator
923 923
      bool operator!=(const ItemIt& i) {
924 924
        return i.idx != idx;
925 925
      }
926 926

	
927 927
    private:
928 928
      const ExtendFindEnum* extendFind;
929 929
      int idx, fdx;
930 930
    };
931 931

	
932 932
  };
933 933

	
934 934
  /// \ingroup auxdat
935 935
  ///
936 936
  /// \brief A \e Union-Find data structure implementation which
937 937
  /// is able to store a priority for each item and retrieve the minimum of
938 938
  /// each class.
939 939
  ///
940 940
  /// A \e Union-Find data structure implementation which is able to
941 941
  /// store a priority for each item and retrieve the minimum of each
942 942
  /// class. In addition, it supports the joining and splitting the
943 943
  /// components. If you don't need this feature then you makes
944 944
  /// better to use the \ref UnionFind class which is more efficient.
945 945
  ///
946 946
  /// The union-find data strcuture based on a (2, 16)-tree with a
947 947
  /// tournament minimum selection on the internal nodes. The insert
948 948
  /// operation takes O(1), the find, set, decrease and increase takes
949 949
  /// O(log(n)), where n is the number of nodes in the current
950 950
  /// component.  The complexity of join and split is O(log(n)*k),
951 951
  /// where n is the sum of the number of the nodes and k is the
952 952
  /// number of joined components or the number of the components
953 953
  /// after the split.
954 954
  ///
955 955
  /// \pre You need to add all the elements by the \ref insert()
956 956
  /// method.
957 957
  template <typename V, typename IM, typename Comp = std::less<V> >
958 958
  class HeapUnionFind {
959 959
  public:
960 960

	
961 961
    ///\e
962 962
    typedef V Value;
963 963
    ///\e
964 964
    typedef typename IM::Key Item;
965 965
    ///\e
966 966
    typedef IM ItemIntMap;
967 967
    ///\e
968 968
    typedef Comp Compare;
969 969

	
970 970
  private:
971 971

	
972 972
    static const int cmax = 16;
973 973

	
974 974
    ItemIntMap& index;
975 975

	
976 976
    struct ClassNode {
977 977
      int parent;
978 978
      int depth;
979 979

	
980 980
      int left, right;
981 981
      int next, prev;
982 982
    };
983 983

	
984 984
    int first_class;
985 985
    int first_free_class;
986 986
    std::vector<ClassNode> classes;
987 987

	
988 988
    int newClass() {
989 989
      if (first_free_class < 0) {
990 990
        int id = classes.size();
991 991
        classes.push_back(ClassNode());
992 992
        return id;
993 993
      } else {
994 994
        int id = first_free_class;
995 995
        first_free_class = classes[id].next;
996 996
        return id;
997 997
      }
998 998
    }
999 999

	
1000 1000
    void deleteClass(int id) {
1001 1001
      classes[id].next = first_free_class;
1002 1002
      first_free_class = id;
1003 1003
    }
1004 1004

	
1005 1005
    struct ItemNode {
1006 1006
      int parent;
1007 1007
      Item item;
1008 1008
      Value prio;
1009 1009
      int next, prev;
1010 1010
      int left, right;
1011 1011
      int size;
1012 1012
    };
1013 1013

	
1014 1014
    int first_free_node;
1015 1015
    std::vector<ItemNode> nodes;
1016 1016

	
1017 1017
    int newNode() {
1018 1018
      if (first_free_node < 0) {
1019 1019
        int id = nodes.size();
1020 1020
        nodes.push_back(ItemNode());
1021 1021
        return id;
1022 1022
      } else {
1023 1023
        int id = first_free_node;
1024 1024
        first_free_node = nodes[id].next;
1025 1025
        return id;
1026 1026
      }
1027 1027
    }
1028 1028

	
1029 1029
    void deleteNode(int id) {
1030 1030
      nodes[id].next = first_free_node;
1031 1031
      first_free_node = id;
1032 1032
    }
1033 1033

	
1034 1034
    Comp comp;
1035 1035

	
1036 1036
    int findClass(int id) const {
1037 1037
      int kd = id;
1038 1038
      while (kd >= 0) {
1039 1039
        kd = nodes[kd].parent;
1040 1040
      }
1041 1041
      return ~kd;
1042 1042
    }
1043 1043

	
1044 1044
    int leftNode(int id) const {
1045 1045
      int kd = ~(classes[id].parent);
1046 1046
      for (int i = 0; i < classes[id].depth; ++i) {
1047 1047
        kd = nodes[kd].left;
1048 1048
      }
1049 1049
      return kd;
1050 1050
    }
1051 1051

	
1052 1052
    int nextNode(int id) const {
1053 1053
      int depth = 0;
1054 1054
      while (id >= 0 && nodes[id].next == -1) {
1055 1055
        id = nodes[id].parent;
1056 1056
        ++depth;
1057 1057
      }
1058 1058
      if (id < 0) {
1059 1059
        return -1;
1060 1060
      }
1061 1061
      id = nodes[id].next;
1062 1062
      while (depth--) {
1063 1063
        id = nodes[id].left;
1064 1064
      }
1065 1065
      return id;
1066 1066
    }
1067 1067

	
1068 1068

	
1069 1069
    void setPrio(int id) {
1070 1070
      int jd = nodes[id].left;
1071 1071
      nodes[id].prio = nodes[jd].prio;
1072 1072
      nodes[id].item = nodes[jd].item;
1073 1073
      jd = nodes[jd].next;
1074 1074
      while (jd != -1) {
1075 1075
        if (comp(nodes[jd].prio, nodes[id].prio)) {
1076 1076
          nodes[id].prio = nodes[jd].prio;
1077 1077
          nodes[id].item = nodes[jd].item;
1078 1078
        }
1079 1079
        jd = nodes[jd].next;
1080 1080
      }
1081 1081
    }
1082 1082

	
1083 1083
    void push(int id, int jd) {
1084 1084
      nodes[id].size = 1;
1085 1085
      nodes[id].left = nodes[id].right = jd;
1086 1086
      nodes[jd].next = nodes[jd].prev = -1;
1087 1087
      nodes[jd].parent = id;
1088 1088
    }
1089 1089

	
1090 1090
    void pushAfter(int id, int jd) {
1091 1091
      int kd = nodes[id].parent;
1092 1092
      if (nodes[id].next != -1) {
1093 1093
        nodes[nodes[id].next].prev = jd;
1094 1094
        if (kd >= 0) {
1095 1095
          nodes[kd].size += 1;
1096 1096
        }
1097 1097
      } else {
1098 1098
        if (kd >= 0) {
1099 1099
          nodes[kd].right = jd;
1100 1100
          nodes[kd].size += 1;
1101 1101
        }
1102 1102
      }
1103 1103
      nodes[jd].next = nodes[id].next;
1104 1104
      nodes[jd].prev = id;
1105 1105
      nodes[id].next = jd;
1106 1106
      nodes[jd].parent = kd;
1107 1107
    }
1108 1108

	
1109 1109
    void pushRight(int id, int jd) {
1110 1110
      nodes[id].size += 1;
1111 1111
      nodes[jd].prev = nodes[id].right;
1112 1112
      nodes[jd].next = -1;
1113 1113
      nodes[nodes[id].right].next = jd;
1114 1114
      nodes[id].right = jd;
1115 1115
      nodes[jd].parent = id;
1116 1116
    }
1117 1117

	
1118 1118
    void popRight(int id) {
1119 1119
      nodes[id].size -= 1;
1120 1120
      int jd = nodes[id].right;
1121 1121
      nodes[nodes[jd].prev].next = -1;
1122 1122
      nodes[id].right = nodes[jd].prev;
1123 1123
    }
1124 1124

	
1125 1125
    void splice(int id, int jd) {
1126 1126
      nodes[id].size += nodes[jd].size;
1127 1127
      nodes[nodes[id].right].next = nodes[jd].left;
1128 1128
      nodes[nodes[jd].left].prev = nodes[id].right;
1129 1129
      int kd = nodes[jd].left;
1130 1130
      while (kd != -1) {
1131 1131
        nodes[kd].parent = id;
1132 1132
        kd = nodes[kd].next;
1133 1133
      }
1134 1134
      nodes[id].right = nodes[jd].right;
1135 1135
    }
1136 1136

	
1137 1137
    void split(int id, int jd) {
1138 1138
      int kd = nodes[id].parent;
1139 1139
      nodes[kd].right = nodes[id].prev;
1140 1140
      nodes[nodes[id].prev].next = -1;
1141 1141

	
1142 1142
      nodes[jd].left = id;
1143 1143
      nodes[id].prev = -1;
1144 1144
      int num = 0;
1145 1145
      while (id != -1) {
1146 1146
        nodes[id].parent = jd;
1147 1147
        nodes[jd].right = id;
1148 1148
        id = nodes[id].next;
1149 1149
        ++num;
1150 1150
      }
1151 1151
      nodes[kd].size -= num;
1152 1152
      nodes[jd].size = num;
1153 1153
    }
1154 1154

	
1155 1155
    void pushLeft(int id, int jd) {
1156 1156
      nodes[id].size += 1;
1157 1157
      nodes[jd].next = nodes[id].left;
1158 1158
      nodes[jd].prev = -1;
1159 1159
      nodes[nodes[id].left].prev = jd;
1160 1160
      nodes[id].left = jd;
1161 1161
      nodes[jd].parent = id;
1162 1162
    }
1163 1163

	
1164 1164
    void popLeft(int id) {
1165 1165
      nodes[id].size -= 1;
1166 1166
      int jd = nodes[id].left;
1167 1167
      nodes[nodes[jd].next].prev = -1;
1168 1168
      nodes[id].left = nodes[jd].next;
1169 1169
    }
1170 1170

	
1171 1171
    void repairLeft(int id) {
1172 1172
      int jd = ~(classes[id].parent);
1173 1173
      while (nodes[jd].left != -1) {
1174 1174
        int kd = nodes[jd].left;
1175 1175
        if (nodes[jd].size == 1) {
1176 1176
          if (nodes[jd].parent < 0) {
1177 1177
            classes[id].parent = ~kd;
1178 1178
            classes[id].depth -= 1;
1179 1179
            nodes[kd].parent = ~id;
1180 1180
            deleteNode(jd);
1181 1181
            jd = kd;
1182 1182
          } else {
1183 1183
            int pd = nodes[jd].parent;
1184 1184
            if (nodes[nodes[jd].next].size < cmax) {
1185 1185
              pushLeft(nodes[jd].next, nodes[jd].left);
1186 1186
              if (less(jd, nodes[jd].next) ||
1187 1187
                  nodes[jd].item == nodes[pd].item) {
1188 1188
                nodes[nodes[jd].next].prio = nodes[jd].prio;
1189 1189
                nodes[nodes[jd].next].item = nodes[jd].item;
1190 1190
              }
1191 1191
              popLeft(pd);
1192 1192
              deleteNode(jd);
1193 1193
              jd = pd;
1194 1194
            } else {
1195 1195
              int ld = nodes[nodes[jd].next].left;
1196 1196
              popLeft(nodes[jd].next);
1197 1197
              pushRight(jd, ld);
1198 1198
              if (less(ld, nodes[jd].left) ||
1199 1199
                  nodes[ld].item == nodes[pd].item) {
1200 1200
                nodes[jd].item = nodes[ld].item;
1201 1201
                nodes[jd].prio = nodes[ld].prio;
1202 1202
              }
1203 1203
              if (nodes[nodes[jd].next].item == nodes[ld].item) {
1204 1204
                setPrio(nodes[jd].next);
1205 1205
              }
1206 1206
              jd = nodes[jd].left;
1207 1207
            }
1208 1208
          }
1209 1209
        } else {
1210 1210
          jd = nodes[jd].left;
1211 1211
        }
1212 1212
      }
1213 1213
    }
1214 1214

	
1215 1215
    void repairRight(int id) {
1216 1216
      int jd = ~(classes[id].parent);
1217 1217
      while (nodes[jd].right != -1) {
1218 1218
        int kd = nodes[jd].right;
1219 1219
        if (nodes[jd].size == 1) {
1220 1220
          if (nodes[jd].parent < 0) {
1221 1221
            classes[id].parent = ~kd;
1222 1222
            classes[id].depth -= 1;
1223 1223
            nodes[kd].parent = ~id;
1224 1224
            deleteNode(jd);
1225 1225
            jd = kd;
1226 1226
          } else {
1227 1227
            int pd = nodes[jd].parent;
1228 1228
            if (nodes[nodes[jd].prev].size < cmax) {
1229 1229
              pushRight(nodes[jd].prev, nodes[jd].right);
1230 1230
              if (less(jd, nodes[jd].prev) ||
1231 1231
                  nodes[jd].item == nodes[pd].item) {
1232 1232
                nodes[nodes[jd].prev].prio = nodes[jd].prio;
1233 1233
                nodes[nodes[jd].prev].item = nodes[jd].item;
1234 1234
              }
1235 1235
              popRight(pd);
1236 1236
              deleteNode(jd);
1237 1237
              jd = pd;
1238 1238
            } else {
1239 1239
              int ld = nodes[nodes[jd].prev].right;
1240 1240
              popRight(nodes[jd].prev);
1241 1241
              pushLeft(jd, ld);
1242 1242
              if (less(ld, nodes[jd].right) ||
1243 1243
                  nodes[ld].item == nodes[pd].item) {
1244 1244
                nodes[jd].item = nodes[ld].item;
1245 1245
                nodes[jd].prio = nodes[ld].prio;
1246 1246
              }
1247 1247
              if (nodes[nodes[jd].prev].item == nodes[ld].item) {
1248 1248
                setPrio(nodes[jd].prev);
1249 1249
              }
1250 1250
              jd = nodes[jd].right;
1251 1251
            }
1252 1252
          }
1253 1253
        } else {
1254 1254
          jd = nodes[jd].right;
1255 1255
        }
1256 1256
      }
1257 1257
    }
1258 1258

	
1259 1259

	
1260 1260
    bool less(int id, int jd) const {
1261 1261
      return comp(nodes[id].prio, nodes[jd].prio);
1262 1262
    }
1263 1263

	
1264 1264
  public:
1265 1265

	
1266 1266
    /// \brief Returns true when the given class is alive.
1267 1267
    ///
1268 1268
    /// Returns true when the given class is alive, ie. the class is
1269 1269
    /// not nested into other class.
1270 1270
    bool alive(int cls) const {
1271 1271
      return classes[cls].parent < 0;
1272 1272
    }
1273 1273

	
1274 1274
    /// \brief Returns true when the given class is trivial.
1275 1275
    ///
1276 1276
    /// Returns true when the given class is trivial, ie. the class
1277 1277
    /// contains just one item directly.
1278 1278
    bool trivial(int cls) const {
1279 1279
      return classes[cls].left == -1;
1280 1280
    }
1281 1281

	
1282 1282
    /// \brief Constructs the union-find.
1283 1283
    ///
1284 1284
    /// Constructs the union-find.
1285 1285
    /// \brief _index The index map of the union-find. The data
1286 1286
    /// structure uses internally for store references.
1287 1287
    HeapUnionFind(ItemIntMap& _index)
1288 1288
      : index(_index), first_class(-1),
1289 1289
        first_free_class(-1), first_free_node(-1) {}
1290 1290

	
1291 1291
    /// \brief Insert a new node into a new component.
1292 1292
    ///
1293 1293
    /// Insert a new node into a new component.
1294 1294
    /// \param item The item of the new node.
1295 1295
    /// \param prio The priority of the new node.
1296 1296
    /// \return The class id of the one-item-heap.
1297 1297
    int insert(const Item& item, const Value& prio) {
1298 1298
      int id = newNode();
1299 1299
      nodes[id].item = item;
1300 1300
      nodes[id].prio = prio;
1301 1301
      nodes[id].size = 0;
1302 1302

	
1303 1303
      nodes[id].prev = -1;
1304 1304
      nodes[id].next = -1;
1305 1305

	
1306 1306
      nodes[id].left = -1;
1307 1307
      nodes[id].right = -1;
1308 1308

	
1309 1309
      nodes[id].item = item;
1310 1310
      index[item] = id;
1311 1311

	
1312 1312
      int class_id = newClass();
1313 1313
      classes[class_id].parent = ~id;
1314 1314
      classes[class_id].depth = 0;
1315 1315

	
1316 1316
      classes[class_id].left = -1;
1317 1317
      classes[class_id].right = -1;
1318 1318

	
1319 1319
      if (first_class != -1) {
1320 1320
        classes[first_class].prev = class_id;
1321 1321
      }
1322 1322
      classes[class_id].next = first_class;
1323 1323
      classes[class_id].prev = -1;
1324 1324
      first_class = class_id;
1325 1325

	
1326 1326
      nodes[id].parent = ~class_id;
1327 1327

	
1328 1328
      return class_id;
1329 1329
    }
1330 1330

	
1331 1331
    /// \brief The class of the item.
1332 1332
    ///
1333 1333
    /// \return The alive class id of the item, which is not nested into
1334 1334
    /// other classes.
1335 1335
    ///
1336 1336
    /// The time complexity is O(log(n)).
1337 1337
    int find(const Item& item) const {
1338 1338
      return findClass(index[item]);
1339 1339
    }
1340 1340

	
1341 1341
    /// \brief Joins the classes.
1342 1342
    ///
1343 1343
    /// The current function joins the given classes. The parameter is
1344 1344
    /// an STL range which should be contains valid class ids. The
1345 1345
    /// time complexity is O(log(n)*k) where n is the overall number
1346 1346
    /// of the joined nodes and k is the number of classes.
1347 1347
    /// \return The class of the joined classes.
1348 1348
    /// \pre The range should contain at least two class ids.
1349 1349
    template <typename Iterator>
1350 1350
    int join(Iterator begin, Iterator end) {
1351 1351
      std::vector<int> cs;
1352 1352
      for (Iterator it = begin; it != end; ++it) {
1353 1353
        cs.push_back(*it);
1354 1354
      }
1355 1355

	
1356 1356
      int class_id = newClass();
1357 1357
      { // creation union-find
1358 1358

	
1359 1359
        if (first_class != -1) {
1360 1360
          classes[first_class].prev = class_id;
1361 1361
        }
1362 1362
        classes[class_id].next = first_class;
1363 1363
        classes[class_id].prev = -1;
1364 1364
        first_class = class_id;
1365 1365

	
1366 1366
        classes[class_id].depth = classes[cs[0]].depth;
1367 1367
        classes[class_id].parent = classes[cs[0]].parent;
1368 1368
        nodes[~(classes[class_id].parent)].parent = ~class_id;
1369 1369

	
1370 1370
        int l = cs[0];
1371 1371

	
1372 1372
        classes[class_id].left = l;
1373 1373
        classes[class_id].right = l;
1374 1374

	
1375 1375
        if (classes[l].next != -1) {
1376 1376
          classes[classes[l].next].prev = classes[l].prev;
1377 1377
        }
1378 1378
        classes[classes[l].prev].next = classes[l].next;
1379 1379

	
1380 1380
        classes[l].prev = -1;
1381 1381
        classes[l].next = -1;
1382 1382

	
1383 1383
        classes[l].depth = leftNode(l);
1384 1384
        classes[l].parent = class_id;
1385 1385

	
1386 1386
      }
1387 1387

	
1388 1388
      { // merging of heap
1389 1389
        int l = class_id;
1390 1390
        for (int ci = 1; ci < int(cs.size()); ++ci) {
1391 1391
          int r = cs[ci];
1392 1392
          int rln = leftNode(r);
1393 1393
          if (classes[l].depth > classes[r].depth) {
1394 1394
            int id = ~(classes[l].parent);
1395 1395
            for (int i = classes[r].depth + 1; i < classes[l].depth; ++i) {
1396 1396
              id = nodes[id].right;
1397 1397
            }
1398 1398
            while (id >= 0 && nodes[id].size == cmax) {
1399 1399
              int new_id = newNode();
1400 1400
              int right_id = nodes[id].right;
1401 1401

	
1402 1402
              popRight(id);
1403 1403
              if (nodes[id].item == nodes[right_id].item) {
1404 1404
                setPrio(id);
1405 1405
              }
1406 1406
              push(new_id, right_id);
1407 1407
              pushRight(new_id, ~(classes[r].parent));
1408 1408

	
1409 1409
              if (less(~classes[r].parent, right_id)) {
1410 1410
                nodes[new_id].item = nodes[~classes[r].parent].item;
1411 1411
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1412 1412
              } else {
1413 1413
                nodes[new_id].item = nodes[right_id].item;
1414 1414
                nodes[new_id].prio = nodes[right_id].prio;
1415 1415
              }
1416 1416

	
1417 1417
              id = nodes[id].parent;
1418 1418
              classes[r].parent = ~new_id;
1419 1419
            }
1420 1420
            if (id < 0) {
1421 1421
              int new_parent = newNode();
1422 1422
              nodes[new_parent].next = -1;
1423 1423
              nodes[new_parent].prev = -1;
1424 1424
              nodes[new_parent].parent = ~l;
1425 1425

	
1426 1426
              push(new_parent, ~(classes[l].parent));
1427 1427
              pushRight(new_parent, ~(classes[r].parent));
1428 1428
              setPrio(new_parent);
1429 1429

	
1430 1430
              classes[l].parent = ~new_parent;
1431 1431
              classes[l].depth += 1;
1432 1432
            } else {
1433 1433
              pushRight(id, ~(classes[r].parent));
1434 1434
              while (id >= 0 && less(~(classes[r].parent), id)) {
1435 1435
                nodes[id].prio = nodes[~(classes[r].parent)].prio;
1436 1436
                nodes[id].item = nodes[~(classes[r].parent)].item;
1437 1437
                id = nodes[id].parent;
1438 1438
              }
1439 1439
            }
1440 1440
          } else if (classes[r].depth > classes[l].depth) {
1441 1441
            int id = ~(classes[r].parent);
1442 1442
            for (int i = classes[l].depth + 1; i < classes[r].depth; ++i) {
1443 1443
              id = nodes[id].left;
1444 1444
            }
1445 1445
            while (id >= 0 && nodes[id].size == cmax) {
1446 1446
              int new_id = newNode();
1447 1447
              int left_id = nodes[id].left;
1448 1448

	
1449 1449
              popLeft(id);
1450 1450
              if (nodes[id].prio == nodes[left_id].prio) {
1451 1451
                setPrio(id);
1452 1452
              }
1453 1453
              push(new_id, left_id);
1454 1454
              pushLeft(new_id, ~(classes[l].parent));
1455 1455

	
1456 1456
              if (less(~classes[l].parent, left_id)) {
1457 1457
                nodes[new_id].item = nodes[~classes[l].parent].item;
1458 1458
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1459 1459
              } else {
1460 1460
                nodes[new_id].item = nodes[left_id].item;
1461 1461
                nodes[new_id].prio = nodes[left_id].prio;
1462 1462
              }
1463 1463

	
1464 1464
              id = nodes[id].parent;
1465 1465
              classes[l].parent = ~new_id;
1466 1466

	
1467 1467
            }
1468 1468
            if (id < 0) {
1469 1469
              int new_parent = newNode();
1470 1470
              nodes[new_parent].next = -1;
1471 1471
              nodes[new_parent].prev = -1;
1472 1472
              nodes[new_parent].parent = ~l;
1473 1473

	
1474 1474
              push(new_parent, ~(classes[r].parent));
1475 1475
              pushLeft(new_parent, ~(classes[l].parent));
1476 1476
              setPrio(new_parent);
1477 1477

	
1478 1478
              classes[r].parent = ~new_parent;
1479 1479
              classes[r].depth += 1;
1480 1480
            } else {
1481 1481
              pushLeft(id, ~(classes[l].parent));
1482 1482
              while (id >= 0 && less(~(classes[l].parent), id)) {
1483 1483
                nodes[id].prio = nodes[~(classes[l].parent)].prio;
1484 1484
                nodes[id].item = nodes[~(classes[l].parent)].item;
1485 1485
                id = nodes[id].parent;
1486 1486
              }
1487 1487
            }
1488 1488
            nodes[~(classes[r].parent)].parent = ~l;
1489 1489
            classes[l].parent = classes[r].parent;
1490 1490
            classes[l].depth = classes[r].depth;
1491 1491
          } else {
1492 1492
            if (classes[l].depth != 0 &&
1493 1493
                nodes[~(classes[l].parent)].size +
1494 1494
                nodes[~(classes[r].parent)].size <= cmax) {
1495 1495
              splice(~(classes[l].parent), ~(classes[r].parent));
1496 1496
              deleteNode(~(classes[r].parent));
1497 1497
              if (less(~(classes[r].parent), ~(classes[l].parent))) {
1498 1498
                nodes[~(classes[l].parent)].prio =
1499 1499
                  nodes[~(classes[r].parent)].prio;
1500 1500
                nodes[~(classes[l].parent)].item =
1501 1501
                  nodes[~(classes[r].parent)].item;
1502 1502
              }
1503 1503
            } else {
1504 1504
              int new_parent = newNode();
1505 1505
              nodes[new_parent].next = nodes[new_parent].prev = -1;
1506 1506
              push(new_parent, ~(classes[l].parent));
1507 1507
              pushRight(new_parent, ~(classes[r].parent));
1508 1508
              setPrio(new_parent);
1509 1509

	
1510 1510
              classes[l].parent = ~new_parent;
1511 1511
              classes[l].depth += 1;
1512 1512
              nodes[new_parent].parent = ~l;
1513 1513
            }
1514 1514
          }
1515 1515
          if (classes[r].next != -1) {
1516 1516
            classes[classes[r].next].prev = classes[r].prev;
1517 1517
          }
1518 1518
          classes[classes[r].prev].next = classes[r].next;
1519 1519

	
1520 1520
          classes[r].prev = classes[l].right;
1521 1521
          classes[classes[l].right].next = r;
1522 1522
          classes[l].right = r;
1523 1523
          classes[r].parent = l;
1524 1524

	
1525 1525
          classes[r].next = -1;
1526 1526
          classes[r].depth = rln;
1527 1527
        }
1528 1528
      }
1529 1529
      return class_id;
1530 1530
    }
1531 1531

	
1532 1532
    /// \brief Split the class to subclasses.
1533 1533
    ///
1534 1534
    /// The current function splits the given class. The join, which
1535 1535
    /// made the current class, stored a reference to the
1536 1536
    /// subclasses. The \c splitClass() member restores the classes
1537 1537
    /// and creates the heaps. The parameter is an STL output iterator
1538 1538
    /// which will be filled with the subclass ids. The time
1539 1539
    /// complexity is O(log(n)*k) where n is the overall number of
1540 1540
    /// nodes in the splitted classes and k is the number of the
1541 1541
    /// classes.
1542 1542
    template <typename Iterator>
1543 1543
    void split(int cls, Iterator out) {
1544 1544
      std::vector<int> cs;
1545 1545
      { // splitting union-find
1546 1546
        int id = cls;
1547 1547
        int l = classes[id].left;
1548 1548

	
1549 1549
        classes[l].parent = classes[id].parent;
1550 1550
        classes[l].depth = classes[id].depth;
1551 1551

	
1552 1552
        nodes[~(classes[l].parent)].parent = ~l;
1553 1553

	
1554 1554
        *out++ = l;
1555 1555

	
1556 1556
        while (l != -1) {
1557 1557
          cs.push_back(l);
1558 1558
          l = classes[l].next;
1559 1559
        }
1560 1560

	
1561 1561
        classes[classes[id].right].next = first_class;
1562 1562
        classes[first_class].prev = classes[id].right;
1563 1563
        first_class = classes[id].left;
1564 1564

	
1565 1565
        if (classes[id].next != -1) {
1566 1566
          classes[classes[id].next].prev = classes[id].prev;
1567 1567
        }
1568 1568
        classes[classes[id].prev].next = classes[id].next;
1569 1569

	
1570 1570
        deleteClass(id);
1571 1571
      }
1572 1572

	
1573 1573
      {
1574 1574
        for (int i = 1; i < int(cs.size()); ++i) {
1575 1575
          int l = classes[cs[i]].depth;
1576 1576
          while (nodes[nodes[l].parent].left == l) {
1577 1577
            l = nodes[l].parent;
1578 1578
          }
1579 1579
          int r = l;
1580 1580
          while (nodes[l].parent >= 0) {
1581 1581
            l = nodes[l].parent;
1582 1582
            int new_node = newNode();
1583 1583

	
1584 1584
            nodes[new_node].prev = -1;
1585 1585
            nodes[new_node].next = -1;
1586 1586

	
1587 1587
            split(r, new_node);
1588 1588
            pushAfter(l, new_node);
1589 1589
            setPrio(l);
1590 1590
            setPrio(new_node);
1591 1591
            r = new_node;
1592 1592
          }
1593 1593
          classes[cs[i]].parent = ~r;
1594 1594
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
1595 1595
          nodes[r].parent = ~cs[i];
1596 1596

	
1597 1597
          nodes[l].next = -1;
1598 1598
          nodes[r].prev = -1;
1599 1599

	
1600 1600
          repairRight(~(nodes[l].parent));
1601 1601
          repairLeft(cs[i]);
1602 1602

	
1603 1603
          *out++ = cs[i];
1604 1604
        }
1605 1605
      }
1606 1606
    }
1607 1607

	
1608 1608
    /// \brief Gives back the priority of the current item.
1609 1609
    ///
1610 1610
    /// Gives back the priority of the current item.
1611 1611
    const Value& operator[](const Item& item) const {
1612 1612
      return nodes[index[item]].prio;
1613 1613
    }
1614 1614

	
1615 1615
    /// \brief Sets the priority of the current item.
1616 1616
    ///
1617 1617
    /// Sets the priority of the current item.
1618 1618
    void set(const Item& item, const Value& prio) {
1619 1619
      if (comp(prio, nodes[index[item]].prio)) {
1620 1620
        decrease(item, prio);
1621 1621
      } else if (!comp(prio, nodes[index[item]].prio)) {
1622 1622
        increase(item, prio);
1623 1623
      }
1624 1624
    }
1625 1625

	
1626 1626
    /// \brief Increase the priority of the current item.
1627 1627
    ///
1628 1628
    /// Increase the priority of the current item.
1629 1629
    void increase(const Item& item, const Value& prio) {
1630 1630
      int id = index[item];
1631 1631
      int kd = nodes[id].parent;
1632 1632
      nodes[id].prio = prio;
1633 1633
      while (kd >= 0 && nodes[kd].item == item) {
1634 1634
        setPrio(kd);
1635 1635
        kd = nodes[kd].parent;
1636 1636
      }
1637 1637
    }
1638 1638

	
1639 1639
    /// \brief Increase the priority of the current item.
1640 1640
    ///
1641 1641
    /// Increase the priority of the current item.
1642 1642
    void decrease(const Item& item, const Value& prio) {
1643 1643
      int id = index[item];
1644 1644
      int kd = nodes[id].parent;
1645 1645
      nodes[id].prio = prio;
1646 1646
      while (kd >= 0 && less(id, kd)) {
1647 1647
        nodes[kd].prio = prio;
1648 1648
        nodes[kd].item = item;
1649 1649
        kd = nodes[kd].parent;
1650 1650
      }
1651 1651
    }
1652 1652

	
1653 1653
    /// \brief Gives back the minimum priority of the class.
1654 1654
    ///
1655 1655
    /// Gives back the minimum priority of the class.
1656 1656
    const Value& classPrio(int cls) const {
1657 1657
      return nodes[~(classes[cls].parent)].prio;
1658 1658
    }
1659 1659

	
1660 1660
    /// \brief Gives back the minimum priority item of the class.
1661 1661
    ///
1662 1662
    /// \return Gives back the minimum priority item of the class.
1663 1663
    const Item& classTop(int cls) const {
1664 1664
      return nodes[~(classes[cls].parent)].item;
1665 1665
    }
1666 1666

	
1667 1667
    /// \brief Gives back a representant item of the class.
1668 1668
    ///
1669 1669
    /// Gives back a representant item of the class.
1670 1670
    /// The representant is indpendent from the priorities of the
1671 1671
    /// items.
1672 1672
    const Item& classRep(int id) const {
1673 1673
      int parent = classes[id].parent;
1674 1674
      return nodes[parent >= 0 ? classes[id].depth : leftNode(id)].item;
1675 1675
    }
1676 1676

	
1677 1677
    /// \brief LEMON style iterator for the items of a class.
1678 1678
    ///
1679 1679
    /// ClassIt is a lemon style iterator for the components. It iterates
1680 1680
    /// on the items of a class. By example if you want to iterate on
1681 1681
    /// each items of each classes then you may write the next code.
1682 1682
    ///\code
1683 1683
    /// for (ClassIt cit(huf); cit != INVALID; ++cit) {
1684 1684
    ///   std::cout << "Class: ";
1685 1685
    ///   for (ItemIt iit(huf, cit); iit != INVALID; ++iit) {
1686 1686
    ///     std::cout << toString(iit) << ' ' << std::endl;
1687 1687
    ///   }
1688 1688
    ///   std::cout << std::endl;
1689 1689
    /// }
1690 1690
    ///\endcode
1691 1691
    class ItemIt {
1692 1692
    private:
1693 1693

	
1694 1694
      const HeapUnionFind* _huf;
1695 1695
      int _id, _lid;
1696 1696

	
1697 1697
    public:
1698 1698

	
1699 1699
      /// \brief Default constructor
1700 1700
      ///
1701 1701
      /// Default constructor
1702 1702
      ItemIt() {}
1703 1703

	
1704 1704
      ItemIt(const HeapUnionFind& huf, int cls) : _huf(&huf) {
1705 1705
        int id = cls;
1706 1706
        int parent = _huf->classes[id].parent;
1707 1707
        if (parent >= 0) {
1708 1708
          _id = _huf->classes[id].depth;
1709 1709
          if (_huf->classes[id].next != -1) {
1710 1710
            _lid = _huf->classes[_huf->classes[id].next].depth;
1711 1711
          } else {
1712 1712
            _lid = -1;
1713 1713
          }
1714 1714
        } else {
1715 1715
          _id = _huf->leftNode(id);
1716 1716
          _lid = -1;
1717 1717
        }
1718 1718
      }
1719 1719

	
1720 1720
      /// \brief Increment operator
1721 1721
      ///
1722 1722
      /// It steps to the next item in the class.
1723 1723
      ItemIt& operator++() {
1724 1724
        _id = _huf->nextNode(_id);
1725 1725
        return *this;
1726 1726
      }
1727 1727

	
1728 1728
      /// \brief Conversion operator
1729 1729
      ///
1730 1730
      /// It converts the iterator to the current item.
1731 1731
      operator const Item&() const {
1732 1732
        return _huf->nodes[_id].item;
1733 1733
      }
1734 1734

	
1735 1735
      /// \brief Equality operator
1736 1736
      ///
1737 1737
      /// Equality operator
1738 1738
      bool operator==(const ItemIt& i) {
1739 1739
        return i._id == _id;
1740 1740
      }
1741 1741

	
1742 1742
      /// \brief Inequality operator
1743 1743
      ///
1744 1744
      /// Inequality operator
1745 1745
      bool operator!=(const ItemIt& i) {
1746 1746
        return i._id != _id;
1747 1747
      }
1748 1748

	
1749 1749
      /// \brief Equality operator
1750 1750
      ///
1751 1751
      /// Equality operator
1752 1752
      bool operator==(Invalid) {
1753 1753
        return _id == _lid;
1754 1754
      }
1755 1755

	
1756 1756
      /// \brief Inequality operator
1757 1757
      ///
1758 1758
      /// Inequality operator
1759 1759
      bool operator!=(Invalid) {
1760 1760
        return _id != _lid;
1761 1761
      }
1762 1762

	
1763 1763
    };
1764 1764

	
1765 1765
    /// \brief Class iterator
1766 1766
    ///
1767 1767
    /// The iterator stores
1768 1768
    class ClassIt {
1769 1769
    private:
1770 1770

	
1771 1771
      const HeapUnionFind* _huf;
1772 1772
      int _id;
1773 1773

	
1774 1774
    public:
1775 1775

	
1776 1776
      ClassIt(const HeapUnionFind& huf)
1777 1777
        : _huf(&huf), _id(huf.first_class) {}
1778 1778

	
1779 1779
      ClassIt(const HeapUnionFind& huf, int cls)
1780 1780
        : _huf(&huf), _id(huf.classes[cls].left) {}
1781 1781

	
1782 1782
      ClassIt(Invalid) : _huf(0), _id(-1) {}
1783 1783

	
1784 1784
      const ClassIt& operator++() {
1785 1785
        _id = _huf->classes[_id].next;
1786 1786
        return *this;
1787 1787
      }
1788 1788

	
1789 1789
      /// \brief Equality operator
1790 1790
      ///
1791 1791
      /// Equality operator
1792 1792
      bool operator==(const ClassIt& i) {
1793 1793
        return i._id == _id;
1794 1794
      }
1795 1795

	
1796 1796
      /// \brief Inequality operator
1797 1797
      ///
1798 1798
      /// Inequality operator
1799 1799
      bool operator!=(const ClassIt& i) {
1800 1800
        return i._id != _id;
1801 1801
      }
1802 1802

	
1803 1803
      operator int() const {
1804 1804
        return _id;
1805 1805
      }
1806 1806

	
1807 1807
    };
1808 1808

	
1809 1809
  };
1810 1810

	
1811 1811
  //! @}
1812 1812

	
1813 1813
} //namespace lemon
1814 1814

	
1815 1815
#endif //LEMON_UNION_FIND_H
0 comments (0 inline)