gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix multiple execution bug in weighted matchings (#356) This chgset also redoes the fix of [28c7ad6f8d91] and its backpont to 1.1, [268a052c3043].
0 2 0
default
2 files changed with 71 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
... ...
@@ -424,803 +424,822 @@
424 424
    /// one of the functions \ref init(), \ref greedyInit() or
425 425
    /// \ref matchingInit() first, then you can start the algorithm with
426 426
    /// \ref startSparse() or \ref startDense().
427 427

	
428 428
    ///@{
429 429

	
430 430
    /// \brief Set the initial matching to the empty matching.
431 431
    ///
432 432
    /// This function sets the initial matching to the empty matching.
433 433
    void init() {
434 434
      createStructures();
435 435
      for(NodeIt n(_graph); n != INVALID; ++n) {
436 436
        (*_matching)[n] = INVALID;
437 437
        (*_status)[n] = UNMATCHED;
438 438
      }
439 439
    }
440 440

	
441 441
    /// \brief Find an initial matching in a greedy way.
442 442
    ///
443 443
    /// This function finds an initial matching in a greedy way.
444 444
    void greedyInit() {
445 445
      createStructures();
446 446
      for (NodeIt n(_graph); n != INVALID; ++n) {
447 447
        (*_matching)[n] = INVALID;
448 448
        (*_status)[n] = UNMATCHED;
449 449
      }
450 450
      for (NodeIt n(_graph); n != INVALID; ++n) {
451 451
        if ((*_matching)[n] == INVALID) {
452 452
          for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
453 453
            Node v = _graph.target(a);
454 454
            if ((*_matching)[v] == INVALID && v != n) {
455 455
              (*_matching)[n] = a;
456 456
              (*_status)[n] = MATCHED;
457 457
              (*_matching)[v] = _graph.oppositeArc(a);
458 458
              (*_status)[v] = MATCHED;
459 459
              break;
460 460
            }
461 461
          }
462 462
        }
463 463
      }
464 464
    }
465 465

	
466 466

	
467 467
    /// \brief Initialize the matching from a map.
468 468
    ///
469 469
    /// This function initializes the matching from a \c bool valued edge
470 470
    /// map. This map should have the property that there are no two incident
471 471
    /// edges with \c true value, i.e. it really contains a matching.
472 472
    /// \return \c true if the map contains a matching.
473 473
    template <typename MatchingMap>
474 474
    bool matchingInit(const MatchingMap& matching) {
475 475
      createStructures();
476 476

	
477 477
      for (NodeIt n(_graph); n != INVALID; ++n) {
478 478
        (*_matching)[n] = INVALID;
479 479
        (*_status)[n] = UNMATCHED;
480 480
      }
481 481
      for(EdgeIt e(_graph); e!=INVALID; ++e) {
482 482
        if (matching[e]) {
483 483

	
484 484
          Node u = _graph.u(e);
485 485
          if ((*_matching)[u] != INVALID) return false;
486 486
          (*_matching)[u] = _graph.direct(e, true);
487 487
          (*_status)[u] = MATCHED;
488 488

	
489 489
          Node v = _graph.v(e);
490 490
          if ((*_matching)[v] != INVALID) return false;
491 491
          (*_matching)[v] = _graph.direct(e, false);
492 492
          (*_status)[v] = MATCHED;
493 493
        }
494 494
      }
495 495
      return true;
496 496
    }
497 497

	
498 498
    /// \brief Start Edmonds' algorithm
499 499
    ///
500 500
    /// This function runs the original Edmonds' algorithm.
501 501
    ///
502 502
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
503 503
    /// called before using this function.
504 504
    void startSparse() {
505 505
      for(NodeIt n(_graph); n != INVALID; ++n) {
506 506
        if ((*_status)[n] == UNMATCHED) {
507 507
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
508 508
          _tree_set->insert(n);
509 509
          (*_status)[n] = EVEN;
510 510
          processSparse(n);
511 511
        }
512 512
      }
513 513
    }
514 514

	
515 515
    /// \brief Start Edmonds' algorithm with a heuristic improvement 
516 516
    /// for dense graphs
517 517
    ///
518 518
    /// This function runs Edmonds' algorithm with a heuristic of postponing
519 519
    /// shrinks, therefore resulting in a faster algorithm for dense graphs.
520 520
    ///
521 521
    /// \pre \ref init(), \ref greedyInit() or \ref matchingInit() must be
522 522
    /// called before using this function.
523 523
    void startDense() {
524 524
      for(NodeIt n(_graph); n != INVALID; ++n) {
525 525
        if ((*_status)[n] == UNMATCHED) {
526 526
          (*_blossom_rep)[_blossom_set->insert(n)] = n;
527 527
          _tree_set->insert(n);
528 528
          (*_status)[n] = EVEN;
529 529
          processDense(n);
530 530
        }
531 531
      }
532 532
    }
533 533

	
534 534

	
535 535
    /// \brief Run Edmonds' algorithm
536 536
    ///
537 537
    /// This function runs Edmonds' algorithm. An additional heuristic of 
538 538
    /// postponing shrinks is used for relatively dense graphs 
539 539
    /// (for which <tt>m>=2*n</tt> holds).
540 540
    void run() {
541 541
      if (countEdges(_graph) < 2 * countNodes(_graph)) {
542 542
        greedyInit();
543 543
        startSparse();
544 544
      } else {
545 545
        init();
546 546
        startDense();
547 547
      }
548 548
    }
549 549

	
550 550
    /// @}
551 551

	
552 552
    /// \name Primal Solution
553 553
    /// Functions to get the primal solution, i.e. the maximum matching.
554 554

	
555 555
    /// @{
556 556

	
557 557
    /// \brief Return the size (cardinality) of the matching.
558 558
    ///
559 559
    /// This function returns the size (cardinality) of the current matching. 
560 560
    /// After run() it returns the size of the maximum matching in the graph.
561 561
    int matchingSize() const {
562 562
      int size = 0;
563 563
      for (NodeIt n(_graph); n != INVALID; ++n) {
564 564
        if ((*_matching)[n] != INVALID) {
565 565
          ++size;
566 566
        }
567 567
      }
568 568
      return size / 2;
569 569
    }
570 570

	
571 571
    /// \brief Return \c true if the given edge is in the matching.
572 572
    ///
573 573
    /// This function returns \c true if the given edge is in the current 
574 574
    /// matching.
575 575
    bool matching(const Edge& edge) const {
576 576
      return edge == (*_matching)[_graph.u(edge)];
577 577
    }
578 578

	
579 579
    /// \brief Return the matching arc (or edge) incident to the given node.
580 580
    ///
581 581
    /// This function returns the matching arc (or edge) incident to the
582 582
    /// given node in the current matching or \c INVALID if the node is 
583 583
    /// not covered by the matching.
584 584
    Arc matching(const Node& n) const {
585 585
      return (*_matching)[n];
586 586
    }
587 587

	
588 588
    /// \brief Return a const reference to the matching map.
589 589
    ///
590 590
    /// This function returns a const reference to a node map that stores
591 591
    /// the matching arc (or edge) incident to each node.
592 592
    const MatchingMap& matchingMap() const {
593 593
      return *_matching;
594 594
    }
595 595

	
596 596
    /// \brief Return the mate of the given node.
597 597
    ///
598 598
    /// This function returns the mate of the given node in the current 
599 599
    /// matching or \c INVALID if the node is not covered by the matching.
600 600
    Node mate(const Node& n) const {
601 601
      return (*_matching)[n] != INVALID ?
602 602
        _graph.target((*_matching)[n]) : INVALID;
603 603
    }
604 604

	
605 605
    /// @}
606 606

	
607 607
    /// \name Dual Solution
608 608
    /// Functions to get the dual solution, i.e. the Gallai-Edmonds 
609 609
    /// decomposition.
610 610

	
611 611
    /// @{
612 612

	
613 613
    /// \brief Return the status of the given node in the Edmonds-Gallai
614 614
    /// decomposition.
615 615
    ///
616 616
    /// This function returns the \ref Status "status" of the given node
617 617
    /// in the Edmonds-Gallai decomposition.
618 618
    Status status(const Node& n) const {
619 619
      return (*_status)[n];
620 620
    }
621 621

	
622 622
    /// \brief Return a const reference to the status map, which stores
623 623
    /// the Edmonds-Gallai decomposition.
624 624
    ///
625 625
    /// This function returns a const reference to a node map that stores the
626 626
    /// \ref Status "status" of each node in the Edmonds-Gallai decomposition.
627 627
    const StatusMap& statusMap() const {
628 628
      return *_status;
629 629
    }
630 630

	
631 631
    /// \brief Return \c true if the given node is in the barrier.
632 632
    ///
633 633
    /// This function returns \c true if the given node is in the barrier.
634 634
    bool barrier(const Node& n) const {
635 635
      return (*_status)[n] == ODD;
636 636
    }
637 637

	
638 638
    /// @}
639 639

	
640 640
  };
641 641

	
642 642
  /// \ingroup matching
643 643
  ///
644 644
  /// \brief Weighted matching in general graphs
645 645
  ///
646 646
  /// This class provides an efficient implementation of Edmond's
647 647
  /// maximum weighted matching algorithm. The implementation is based
648 648
  /// on extensive use of priority queues and provides
649 649
  /// \f$O(nm\log n)\f$ time complexity.
650 650
  ///
651 651
  /// The maximum weighted matching problem is to find a subset of the 
652 652
  /// edges in an undirected graph with maximum overall weight for which 
653 653
  /// each node has at most one incident edge.
654 654
  /// It can be formulated with the following linear program.
655 655
  /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
656 656
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
657 657
      \quad \forall B\in\mathcal{O}\f] */
658 658
  /// \f[x_e \ge 0\quad \forall e\in E\f]
659 659
  /// \f[\max \sum_{e\in E}x_ew_e\f]
660 660
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
661 661
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
662 662
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
663 663
  /// subsets of the nodes.
664 664
  ///
665 665
  /// The algorithm calculates an optimal matching and a proof of the
666 666
  /// optimality. The solution of the dual problem can be used to check
667 667
  /// the result of the algorithm. The dual linear problem is the
668 668
  /// following.
669 669
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
670 670
      z_B \ge w_{uv} \quad \forall uv\in E\f] */
671 671
  /// \f[y_u \ge 0 \quad \forall u \in V\f]
672 672
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
673 673
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
674 674
      \frac{\vert B \vert - 1}{2}z_B\f] */
675 675
  ///
676 676
  /// The algorithm can be executed with the run() function. 
677 677
  /// After it the matching (the primal solution) and the dual solution
678 678
  /// can be obtained using the query functions and the 
679 679
  /// \ref MaxWeightedMatching::BlossomIt "BlossomIt" nested class, 
680 680
  /// which is able to iterate on the nodes of a blossom. 
681 681
  /// If the value type is integer, then the dual solution is multiplied
682 682
  /// by \ref MaxWeightedMatching::dualScale "4".
683 683
  ///
684 684
  /// \tparam GR The undirected graph type the algorithm runs on.
685 685
  /// \tparam WM The type edge weight map. The default type is 
686 686
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
687 687
#ifdef DOXYGEN
688 688
  template <typename GR, typename WM>
689 689
#else
690 690
  template <typename GR,
691 691
            typename WM = typename GR::template EdgeMap<int> >
692 692
#endif
693 693
  class MaxWeightedMatching {
694 694
  public:
695 695

	
696 696
    /// The graph type of the algorithm
697 697
    typedef GR Graph;
698 698
    /// The type of the edge weight map
699 699
    typedef WM WeightMap;
700 700
    /// The value type of the edge weights
701 701
    typedef typename WeightMap::Value Value;
702 702

	
703 703
    /// The type of the matching map
704 704
    typedef typename Graph::template NodeMap<typename Graph::Arc>
705 705
    MatchingMap;
706 706

	
707 707
    /// \brief Scaling factor for dual solution
708 708
    ///
709 709
    /// Scaling factor for dual solution. It is equal to 4 or 1
710 710
    /// according to the value type.
711 711
    static const int dualScale =
712 712
      std::numeric_limits<Value>::is_integer ? 4 : 1;
713 713

	
714 714
  private:
715 715

	
716 716
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
717 717

	
718 718
    typedef typename Graph::template NodeMap<Value> NodePotential;
719 719
    typedef std::vector<Node> BlossomNodeList;
720 720

	
721 721
    struct BlossomVariable {
722 722
      int begin, end;
723 723
      Value value;
724 724

	
725 725
      BlossomVariable(int _begin, int _end, Value _value)
726 726
        : begin(_begin), end(_end), value(_value) {}
727 727

	
728 728
    };
729 729

	
730 730
    typedef std::vector<BlossomVariable> BlossomPotential;
731 731

	
732 732
    const Graph& _graph;
733 733
    const WeightMap& _weight;
734 734

	
735 735
    MatchingMap* _matching;
736 736

	
737 737
    NodePotential* _node_potential;
738 738

	
739 739
    BlossomPotential _blossom_potential;
740 740
    BlossomNodeList _blossom_node_list;
741 741

	
742 742
    int _node_num;
743 743
    int _blossom_num;
744 744

	
745 745
    typedef RangeMap<int> IntIntMap;
746 746

	
747 747
    enum Status {
748 748
      EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
749 749
    };
750 750

	
751 751
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
752 752
    struct BlossomData {
753 753
      int tree;
754 754
      Status status;
755 755
      Arc pred, next;
756 756
      Value pot, offset;
757 757
      Node base;
758 758
    };
759 759

	
760 760
    IntNodeMap *_blossom_index;
761 761
    BlossomSet *_blossom_set;
762 762
    RangeMap<BlossomData>* _blossom_data;
763 763

	
764 764
    IntNodeMap *_node_index;
765 765
    IntArcMap *_node_heap_index;
766 766

	
767 767
    struct NodeData {
768 768

	
769 769
      NodeData(IntArcMap& node_heap_index)
770 770
        : heap(node_heap_index) {}
771 771

	
772 772
      int blossom;
773 773
      Value pot;
774 774
      BinHeap<Value, IntArcMap> heap;
775 775
      std::map<int, Arc> heap_index;
776 776

	
777 777
      int tree;
778 778
    };
779 779

	
780 780
    RangeMap<NodeData>* _node_data;
781 781

	
782 782
    typedef ExtendFindEnum<IntIntMap> TreeSet;
783 783

	
784 784
    IntIntMap *_tree_set_index;
785 785
    TreeSet *_tree_set;
786 786

	
787 787
    IntNodeMap *_delta1_index;
788 788
    BinHeap<Value, IntNodeMap> *_delta1;
789 789

	
790 790
    IntIntMap *_delta2_index;
791 791
    BinHeap<Value, IntIntMap> *_delta2;
792 792

	
793 793
    IntEdgeMap *_delta3_index;
794 794
    BinHeap<Value, IntEdgeMap> *_delta3;
795 795

	
796 796
    IntIntMap *_delta4_index;
797 797
    BinHeap<Value, IntIntMap> *_delta4;
798 798

	
799 799
    Value _delta_sum;
800 800

	
801 801
    void createStructures() {
802 802
      _node_num = countNodes(_graph);
803 803
      _blossom_num = _node_num * 3 / 2;
804 804

	
805 805
      if (!_matching) {
806 806
        _matching = new MatchingMap(_graph);
807 807
      }
808

	
808 809
      if (!_node_potential) {
809 810
        _node_potential = new NodePotential(_graph);
810 811
      }
812

	
811 813
      if (!_blossom_set) {
812 814
        _blossom_index = new IntNodeMap(_graph);
813 815
        _blossom_set = new BlossomSet(*_blossom_index);
814 816
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
817
      } else if (_blossom_data->size() != _blossom_num) {
818
        delete _blossom_data;
819
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
815 820
      }
816 821

	
817 822
      if (!_node_index) {
818 823
        _node_index = new IntNodeMap(_graph);
819 824
        _node_heap_index = new IntArcMap(_graph);
820 825
        _node_data = new RangeMap<NodeData>(_node_num,
821
                                              NodeData(*_node_heap_index));
826
                                            NodeData(*_node_heap_index));
827
      } else {
828
        delete _node_data;
829
        _node_data = new RangeMap<NodeData>(_node_num,
830
                                            NodeData(*_node_heap_index));
822 831
      }
823 832

	
824 833
      if (!_tree_set) {
825 834
        _tree_set_index = new IntIntMap(_blossom_num);
826 835
        _tree_set = new TreeSet(*_tree_set_index);
836
      } else {
837
        _tree_set_index->resize(_blossom_num);
827 838
      }
839

	
828 840
      if (!_delta1) {
829 841
        _delta1_index = new IntNodeMap(_graph);
830 842
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
831 843
      }
844

	
832 845
      if (!_delta2) {
833 846
        _delta2_index = new IntIntMap(_blossom_num);
834 847
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
848
      } else {
849
        _delta2_index->resize(_blossom_num);
835 850
      }
851

	
836 852
      if (!_delta3) {
837 853
        _delta3_index = new IntEdgeMap(_graph);
838 854
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
839 855
      }
856

	
840 857
      if (!_delta4) {
841 858
        _delta4_index = new IntIntMap(_blossom_num);
842 859
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
860
      } else {
861
        _delta4_index->resize(_blossom_num);
843 862
      }
844 863
    }
845 864

	
846 865
    void destroyStructures() {
847 866
      _node_num = countNodes(_graph);
848 867
      _blossom_num = _node_num * 3 / 2;
849 868

	
850 869
      if (_matching) {
851 870
        delete _matching;
852 871
      }
853 872
      if (_node_potential) {
854 873
        delete _node_potential;
855 874
      }
856 875
      if (_blossom_set) {
857 876
        delete _blossom_index;
858 877
        delete _blossom_set;
859 878
        delete _blossom_data;
860 879
      }
861 880

	
862 881
      if (_node_index) {
863 882
        delete _node_index;
864 883
        delete _node_heap_index;
865 884
        delete _node_data;
866 885
      }
867 886

	
868 887
      if (_tree_set) {
869 888
        delete _tree_set_index;
870 889
        delete _tree_set;
871 890
      }
872 891
      if (_delta1) {
873 892
        delete _delta1_index;
874 893
        delete _delta1;
875 894
      }
876 895
      if (_delta2) {
877 896
        delete _delta2_index;
878 897
        delete _delta2;
879 898
      }
880 899
      if (_delta3) {
881 900
        delete _delta3_index;
882 901
        delete _delta3;
883 902
      }
884 903
      if (_delta4) {
885 904
        delete _delta4_index;
886 905
        delete _delta4;
887 906
      }
888 907
    }
889 908

	
890 909
    void matchedToEven(int blossom, int tree) {
891 910
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
892 911
        _delta2->erase(blossom);
893 912
      }
894 913

	
895 914
      if (!_blossom_set->trivial(blossom)) {
896 915
        (*_blossom_data)[blossom].pot -=
897 916
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
898 917
      }
899 918

	
900 919
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
901 920
           n != INVALID; ++n) {
902 921

	
903 922
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
904 923
        int ni = (*_node_index)[n];
905 924

	
906 925
        (*_node_data)[ni].heap.clear();
907 926
        (*_node_data)[ni].heap_index.clear();
908 927

	
909 928
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
910 929

	
911 930
        _delta1->push(n, (*_node_data)[ni].pot);
912 931

	
913 932
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
914 933
          Node v = _graph.source(e);
915 934
          int vb = _blossom_set->find(v);
916 935
          int vi = (*_node_index)[v];
917 936

	
918 937
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
919 938
            dualScale * _weight[e];
920 939

	
921 940
          if ((*_blossom_data)[vb].status == EVEN) {
922 941
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
923 942
              _delta3->push(e, rw / 2);
924 943
            }
925 944
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
926 945
            if (_delta3->state(e) != _delta3->IN_HEAP) {
927 946
              _delta3->push(e, rw);
928 947
            }
929 948
          } else {
930 949
            typename std::map<int, Arc>::iterator it =
931 950
              (*_node_data)[vi].heap_index.find(tree);
932 951

	
933 952
            if (it != (*_node_data)[vi].heap_index.end()) {
934 953
              if ((*_node_data)[vi].heap[it->second] > rw) {
935 954
                (*_node_data)[vi].heap.replace(it->second, e);
936 955
                (*_node_data)[vi].heap.decrease(e, rw);
937 956
                it->second = e;
938 957
              }
939 958
            } else {
940 959
              (*_node_data)[vi].heap.push(e, rw);
941 960
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
942 961
            }
943 962

	
944 963
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
945 964
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
946 965

	
947 966
              if ((*_blossom_data)[vb].status == MATCHED) {
948 967
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
949 968
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
950 969
                               (*_blossom_data)[vb].offset);
951 970
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
952 971
                           (*_blossom_data)[vb].offset){
953 972
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
954 973
                                   (*_blossom_data)[vb].offset);
955 974
                }
956 975
              }
957 976
            }
958 977
          }
959 978
        }
960 979
      }
961 980
      (*_blossom_data)[blossom].offset = 0;
962 981
    }
963 982

	
964 983
    void matchedToOdd(int blossom) {
965 984
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
966 985
        _delta2->erase(blossom);
967 986
      }
968 987
      (*_blossom_data)[blossom].offset += _delta_sum;
969 988
      if (!_blossom_set->trivial(blossom)) {
970 989
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
971 990
                     (*_blossom_data)[blossom].offset);
972 991
      }
973 992
    }
974 993

	
975 994
    void evenToMatched(int blossom, int tree) {
976 995
      if (!_blossom_set->trivial(blossom)) {
977 996
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
978 997
      }
979 998

	
980 999
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
981 1000
           n != INVALID; ++n) {
982 1001
        int ni = (*_node_index)[n];
983 1002
        (*_node_data)[ni].pot -= _delta_sum;
984 1003

	
985 1004
        _delta1->erase(n);
986 1005

	
987 1006
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
988 1007
          Node v = _graph.source(e);
989 1008
          int vb = _blossom_set->find(v);
990 1009
          int vi = (*_node_index)[v];
991 1010

	
992 1011
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
993 1012
            dualScale * _weight[e];
994 1013

	
995 1014
          if (vb == blossom) {
996 1015
            if (_delta3->state(e) == _delta3->IN_HEAP) {
997 1016
              _delta3->erase(e);
998 1017
            }
999 1018
          } else if ((*_blossom_data)[vb].status == EVEN) {
1000 1019

	
1001 1020
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1002 1021
              _delta3->erase(e);
1003 1022
            }
1004 1023

	
1005 1024
            int vt = _tree_set->find(vb);
1006 1025

	
1007 1026
            if (vt != tree) {
1008 1027

	
1009 1028
              Arc r = _graph.oppositeArc(e);
1010 1029

	
1011 1030
              typename std::map<int, Arc>::iterator it =
1012 1031
                (*_node_data)[ni].heap_index.find(vt);
1013 1032

	
1014 1033
              if (it != (*_node_data)[ni].heap_index.end()) {
1015 1034
                if ((*_node_data)[ni].heap[it->second] > rw) {
1016 1035
                  (*_node_data)[ni].heap.replace(it->second, r);
1017 1036
                  (*_node_data)[ni].heap.decrease(r, rw);
1018 1037
                  it->second = r;
1019 1038
                }
1020 1039
              } else {
1021 1040
                (*_node_data)[ni].heap.push(r, rw);
1022 1041
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
1023 1042
              }
1024 1043

	
1025 1044
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
1026 1045
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
1027 1046

	
1028 1047
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
1029 1048
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1030 1049
                               (*_blossom_data)[blossom].offset);
1031 1050
                } else if ((*_delta2)[blossom] >
1032 1051
                           _blossom_set->classPrio(blossom) -
1033 1052
                           (*_blossom_data)[blossom].offset){
1034 1053
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
1035 1054
                                   (*_blossom_data)[blossom].offset);
1036 1055
                }
1037 1056
              }
1038 1057
            }
1039 1058

	
1040 1059
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1041 1060
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1042 1061
              _delta3->erase(e);
1043 1062
            }
1044 1063
          } else {
1045 1064

	
1046 1065
            typename std::map<int, Arc>::iterator it =
1047 1066
              (*_node_data)[vi].heap_index.find(tree);
1048 1067

	
1049 1068
            if (it != (*_node_data)[vi].heap_index.end()) {
1050 1069
              (*_node_data)[vi].heap.erase(it->second);
1051 1070
              (*_node_data)[vi].heap_index.erase(it);
1052 1071
              if ((*_node_data)[vi].heap.empty()) {
1053 1072
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
1054 1073
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
1055 1074
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
1056 1075
              }
1057 1076

	
1058 1077
              if ((*_blossom_data)[vb].status == MATCHED) {
1059 1078
                if (_blossom_set->classPrio(vb) ==
1060 1079
                    std::numeric_limits<Value>::max()) {
1061 1080
                  _delta2->erase(vb);
1062 1081
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
1063 1082
                           (*_blossom_data)[vb].offset) {
1064 1083
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
1065 1084
                                   (*_blossom_data)[vb].offset);
1066 1085
                }
1067 1086
              }
1068 1087
            }
1069 1088
          }
1070 1089
        }
1071 1090
      }
1072 1091
    }
1073 1092

	
1074 1093
    void oddToMatched(int blossom) {
1075 1094
      (*_blossom_data)[blossom].offset -= _delta_sum;
1076 1095

	
1077 1096
      if (_blossom_set->classPrio(blossom) !=
1078 1097
          std::numeric_limits<Value>::max()) {
1079 1098
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
1080 1099
                       (*_blossom_data)[blossom].offset);
1081 1100
      }
1082 1101

	
1083 1102
      if (!_blossom_set->trivial(blossom)) {
1084 1103
        _delta4->erase(blossom);
1085 1104
      }
1086 1105
    }
1087 1106

	
1088 1107
    void oddToEven(int blossom, int tree) {
1089 1108
      if (!_blossom_set->trivial(blossom)) {
1090 1109
        _delta4->erase(blossom);
1091 1110
        (*_blossom_data)[blossom].pot -=
1092 1111
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
1093 1112
      }
1094 1113

	
1095 1114
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1096 1115
           n != INVALID; ++n) {
1097 1116
        int ni = (*_node_index)[n];
1098 1117

	
1099 1118
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1100 1119

	
1101 1120
        (*_node_data)[ni].heap.clear();
1102 1121
        (*_node_data)[ni].heap_index.clear();
1103 1122
        (*_node_data)[ni].pot +=
1104 1123
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
1105 1124

	
1106 1125
        _delta1->push(n, (*_node_data)[ni].pot);
1107 1126

	
1108 1127
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1109 1128
          Node v = _graph.source(e);
1110 1129
          int vb = _blossom_set->find(v);
1111 1130
          int vi = (*_node_index)[v];
1112 1131

	
1113 1132
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1114 1133
            dualScale * _weight[e];
1115 1134

	
1116 1135
          if ((*_blossom_data)[vb].status == EVEN) {
1117 1136
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
1118 1137
              _delta3->push(e, rw / 2);
1119 1138
            }
1120 1139
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
1121 1140
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1122 1141
              _delta3->push(e, rw);
1123 1142
            }
1124 1143
          } else {
1125 1144

	
1126 1145
            typename std::map<int, Arc>::iterator it =
1127 1146
              (*_node_data)[vi].heap_index.find(tree);
1128 1147

	
1129 1148
            if (it != (*_node_data)[vi].heap_index.end()) {
1130 1149
              if ((*_node_data)[vi].heap[it->second] > rw) {
1131 1150
                (*_node_data)[vi].heap.replace(it->second, e);
1132 1151
                (*_node_data)[vi].heap.decrease(e, rw);
1133 1152
                it->second = e;
1134 1153
              }
1135 1154
            } else {
1136 1155
              (*_node_data)[vi].heap.push(e, rw);
1137 1156
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
1138 1157
            }
1139 1158

	
1140 1159
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
1141 1160
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
1142 1161

	
1143 1162
              if ((*_blossom_data)[vb].status == MATCHED) {
1144 1163
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
1145 1164
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
1146 1165
                               (*_blossom_data)[vb].offset);
1147 1166
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
1148 1167
                           (*_blossom_data)[vb].offset) {
1149 1168
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
1150 1169
                                   (*_blossom_data)[vb].offset);
1151 1170
                }
1152 1171
              }
1153 1172
            }
1154 1173
          }
1155 1174
        }
1156 1175
      }
1157 1176
      (*_blossom_data)[blossom].offset = 0;
1158 1177
    }
1159 1178

	
1160 1179

	
1161 1180
    void matchedToUnmatched(int blossom) {
1162 1181
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1163 1182
        _delta2->erase(blossom);
1164 1183
      }
1165 1184

	
1166 1185
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1167 1186
           n != INVALID; ++n) {
1168 1187
        int ni = (*_node_index)[n];
1169 1188

	
1170 1189
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
1171 1190

	
1172 1191
        (*_node_data)[ni].heap.clear();
1173 1192
        (*_node_data)[ni].heap_index.clear();
1174 1193

	
1175 1194
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1176 1195
          Node v = _graph.target(e);
1177 1196
          int vb = _blossom_set->find(v);
1178 1197
          int vi = (*_node_index)[v];
1179 1198

	
1180 1199
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1181 1200
            dualScale * _weight[e];
1182 1201

	
1183 1202
          if ((*_blossom_data)[vb].status == EVEN) {
1184 1203
            if (_delta3->state(e) != _delta3->IN_HEAP) {
1185 1204
              _delta3->push(e, rw);
1186 1205
            }
1187 1206
          }
1188 1207
        }
1189 1208
      }
1190 1209
    }
1191 1210

	
1192 1211
    void unmatchedToMatched(int blossom) {
1193 1212
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
1194 1213
           n != INVALID; ++n) {
1195 1214
        int ni = (*_node_index)[n];
1196 1215

	
1197 1216
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
1198 1217
          Node v = _graph.source(e);
1199 1218
          int vb = _blossom_set->find(v);
1200 1219
          int vi = (*_node_index)[v];
1201 1220

	
1202 1221
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
1203 1222
            dualScale * _weight[e];
1204 1223

	
1205 1224
          if (vb == blossom) {
1206 1225
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1207 1226
              _delta3->erase(e);
1208 1227
            }
1209 1228
          } else if ((*_blossom_data)[vb].status == EVEN) {
1210 1229

	
1211 1230
            if (_delta3->state(e) == _delta3->IN_HEAP) {
1212 1231
              _delta3->erase(e);
1213 1232
            }
1214 1233

	
1215 1234
            int vt = _tree_set->find(vb);
1216 1235

	
1217 1236
            Arc r = _graph.oppositeArc(e);
1218 1237

	
1219 1238
            typename std::map<int, Arc>::iterator it =
1220 1239
              (*_node_data)[ni].heap_index.find(vt);
1221 1240

	
1222 1241
            if (it != (*_node_data)[ni].heap_index.end()) {
1223 1242
              if ((*_node_data)[ni].heap[it->second] > rw) {
1224 1243
                (*_node_data)[ni].heap.replace(it->second, r);
1225 1244
                (*_node_data)[ni].heap.decrease(r, rw);
1226 1245
                it->second = r;
... ...
@@ -1304,1941 +1323,1982 @@
1304 1323

	
1305 1324
      int left = _blossom_set->find(_graph.u(edge));
1306 1325
      int right = _blossom_set->find(_graph.v(edge));
1307 1326

	
1308 1327
      if ((*_blossom_data)[left].status == EVEN) {
1309 1328
        int left_tree = _tree_set->find(left);
1310 1329
        alternatePath(left, left_tree);
1311 1330
        destroyTree(left_tree);
1312 1331
      } else {
1313 1332
        (*_blossom_data)[left].status = MATCHED;
1314 1333
        unmatchedToMatched(left);
1315 1334
      }
1316 1335

	
1317 1336
      if ((*_blossom_data)[right].status == EVEN) {
1318 1337
        int right_tree = _tree_set->find(right);
1319 1338
        alternatePath(right, right_tree);
1320 1339
        destroyTree(right_tree);
1321 1340
      } else {
1322 1341
        (*_blossom_data)[right].status = MATCHED;
1323 1342
        unmatchedToMatched(right);
1324 1343
      }
1325 1344

	
1326 1345
      (*_blossom_data)[left].next = _graph.direct(edge, true);
1327 1346
      (*_blossom_data)[right].next = _graph.direct(edge, false);
1328 1347
    }
1329 1348

	
1330 1349
    void extendOnArc(const Arc& arc) {
1331 1350
      int base = _blossom_set->find(_graph.target(arc));
1332 1351
      int tree = _tree_set->find(base);
1333 1352

	
1334 1353
      int odd = _blossom_set->find(_graph.source(arc));
1335 1354
      _tree_set->insert(odd, tree);
1336 1355
      (*_blossom_data)[odd].status = ODD;
1337 1356
      matchedToOdd(odd);
1338 1357
      (*_blossom_data)[odd].pred = arc;
1339 1358

	
1340 1359
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
1341 1360
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
1342 1361
      _tree_set->insert(even, tree);
1343 1362
      (*_blossom_data)[even].status = EVEN;
1344 1363
      matchedToEven(even, tree);
1345 1364
    }
1346 1365

	
1347 1366
    void shrinkOnEdge(const Edge& edge, int tree) {
1348 1367
      int nca = -1;
1349 1368
      std::vector<int> left_path, right_path;
1350 1369

	
1351 1370
      {
1352 1371
        std::set<int> left_set, right_set;
1353 1372
        int left = _blossom_set->find(_graph.u(edge));
1354 1373
        left_path.push_back(left);
1355 1374
        left_set.insert(left);
1356 1375

	
1357 1376
        int right = _blossom_set->find(_graph.v(edge));
1358 1377
        right_path.push_back(right);
1359 1378
        right_set.insert(right);
1360 1379

	
1361 1380
        while (true) {
1362 1381

	
1363 1382
          if ((*_blossom_data)[left].pred == INVALID) break;
1364 1383

	
1365 1384
          left =
1366 1385
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1367 1386
          left_path.push_back(left);
1368 1387
          left =
1369 1388
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
1370 1389
          left_path.push_back(left);
1371 1390

	
1372 1391
          left_set.insert(left);
1373 1392

	
1374 1393
          if (right_set.find(left) != right_set.end()) {
1375 1394
            nca = left;
1376 1395
            break;
1377 1396
          }
1378 1397

	
1379 1398
          if ((*_blossom_data)[right].pred == INVALID) break;
1380 1399

	
1381 1400
          right =
1382 1401
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1383 1402
          right_path.push_back(right);
1384 1403
          right =
1385 1404
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
1386 1405
          right_path.push_back(right);
1387 1406

	
1388 1407
          right_set.insert(right);
1389 1408

	
1390 1409
          if (left_set.find(right) != left_set.end()) {
1391 1410
            nca = right;
1392 1411
            break;
1393 1412
          }
1394 1413

	
1395 1414
        }
1396 1415

	
1397 1416
        if (nca == -1) {
1398 1417
          if ((*_blossom_data)[left].pred == INVALID) {
1399 1418
            nca = right;
1400 1419
            while (left_set.find(nca) == left_set.end()) {
1401 1420
              nca =
1402 1421
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1403 1422
              right_path.push_back(nca);
1404 1423
              nca =
1405 1424
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1406 1425
              right_path.push_back(nca);
1407 1426
            }
1408 1427
          } else {
1409 1428
            nca = left;
1410 1429
            while (right_set.find(nca) == right_set.end()) {
1411 1430
              nca =
1412 1431
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1413 1432
              left_path.push_back(nca);
1414 1433
              nca =
1415 1434
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
1416 1435
              left_path.push_back(nca);
1417 1436
            }
1418 1437
          }
1419 1438
        }
1420 1439
      }
1421 1440

	
1422 1441
      std::vector<int> subblossoms;
1423 1442
      Arc prev;
1424 1443

	
1425 1444
      prev = _graph.direct(edge, true);
1426 1445
      for (int i = 0; left_path[i] != nca; i += 2) {
1427 1446
        subblossoms.push_back(left_path[i]);
1428 1447
        (*_blossom_data)[left_path[i]].next = prev;
1429 1448
        _tree_set->erase(left_path[i]);
1430 1449

	
1431 1450
        subblossoms.push_back(left_path[i + 1]);
1432 1451
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
1433 1452
        oddToEven(left_path[i + 1], tree);
1434 1453
        _tree_set->erase(left_path[i + 1]);
1435 1454
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
1436 1455
      }
1437 1456

	
1438 1457
      int k = 0;
1439 1458
      while (right_path[k] != nca) ++k;
1440 1459

	
1441 1460
      subblossoms.push_back(nca);
1442 1461
      (*_blossom_data)[nca].next = prev;
1443 1462

	
1444 1463
      for (int i = k - 2; i >= 0; i -= 2) {
1445 1464
        subblossoms.push_back(right_path[i + 1]);
1446 1465
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
1447 1466
        oddToEven(right_path[i + 1], tree);
1448 1467
        _tree_set->erase(right_path[i + 1]);
1449 1468

	
1450 1469
        (*_blossom_data)[right_path[i + 1]].next =
1451 1470
          (*_blossom_data)[right_path[i + 1]].pred;
1452 1471

	
1453 1472
        subblossoms.push_back(right_path[i]);
1454 1473
        _tree_set->erase(right_path[i]);
1455 1474
      }
1456 1475

	
1457 1476
      int surface =
1458 1477
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
1459 1478

	
1460 1479
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1461 1480
        if (!_blossom_set->trivial(subblossoms[i])) {
1462 1481
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
1463 1482
        }
1464 1483
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
1465 1484
      }
1466 1485

	
1467 1486
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
1468 1487
      (*_blossom_data)[surface].offset = 0;
1469 1488
      (*_blossom_data)[surface].status = EVEN;
1470 1489
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
1471 1490
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
1472 1491

	
1473 1492
      _tree_set->insert(surface, tree);
1474 1493
      _tree_set->erase(nca);
1475 1494
    }
1476 1495

	
1477 1496
    void splitBlossom(int blossom) {
1478 1497
      Arc next = (*_blossom_data)[blossom].next;
1479 1498
      Arc pred = (*_blossom_data)[blossom].pred;
1480 1499

	
1481 1500
      int tree = _tree_set->find(blossom);
1482 1501

	
1483 1502
      (*_blossom_data)[blossom].status = MATCHED;
1484 1503
      oddToMatched(blossom);
1485 1504
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
1486 1505
        _delta2->erase(blossom);
1487 1506
      }
1488 1507

	
1489 1508
      std::vector<int> subblossoms;
1490 1509
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
1491 1510

	
1492 1511
      Value offset = (*_blossom_data)[blossom].offset;
1493 1512
      int b = _blossom_set->find(_graph.source(pred));
1494 1513
      int d = _blossom_set->find(_graph.source(next));
1495 1514

	
1496 1515
      int ib = -1, id = -1;
1497 1516
      for (int i = 0; i < int(subblossoms.size()); ++i) {
1498 1517
        if (subblossoms[i] == b) ib = i;
1499 1518
        if (subblossoms[i] == d) id = i;
1500 1519

	
1501 1520
        (*_blossom_data)[subblossoms[i]].offset = offset;
1502 1521
        if (!_blossom_set->trivial(subblossoms[i])) {
1503 1522
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
1504 1523
        }
1505 1524
        if (_blossom_set->classPrio(subblossoms[i]) !=
1506 1525
            std::numeric_limits<Value>::max()) {
1507 1526
          _delta2->push(subblossoms[i],
1508 1527
                        _blossom_set->classPrio(subblossoms[i]) -
1509 1528
                        (*_blossom_data)[subblossoms[i]].offset);
1510 1529
        }
1511 1530
      }
1512 1531

	
1513 1532
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
1514 1533
        for (int i = (id + 1) % subblossoms.size();
1515 1534
             i != ib; i = (i + 2) % subblossoms.size()) {
1516 1535
          int sb = subblossoms[i];
1517 1536
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1518 1537
          (*_blossom_data)[sb].next =
1519 1538
            _graph.oppositeArc((*_blossom_data)[tb].next);
1520 1539
        }
1521 1540

	
1522 1541
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
1523 1542
          int sb = subblossoms[i];
1524 1543
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1525 1544
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1526 1545

	
1527 1546
          (*_blossom_data)[sb].status = ODD;
1528 1547
          matchedToOdd(sb);
1529 1548
          _tree_set->insert(sb, tree);
1530 1549
          (*_blossom_data)[sb].pred = pred;
1531 1550
          (*_blossom_data)[sb].next =
1532 1551
                           _graph.oppositeArc((*_blossom_data)[tb].next);
1533 1552

	
1534 1553
          pred = (*_blossom_data)[ub].next;
1535 1554

	
1536 1555
          (*_blossom_data)[tb].status = EVEN;
1537 1556
          matchedToEven(tb, tree);
1538 1557
          _tree_set->insert(tb, tree);
1539 1558
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
1540 1559
        }
1541 1560

	
1542 1561
        (*_blossom_data)[subblossoms[id]].status = ODD;
1543 1562
        matchedToOdd(subblossoms[id]);
1544 1563
        _tree_set->insert(subblossoms[id], tree);
1545 1564
        (*_blossom_data)[subblossoms[id]].next = next;
1546 1565
        (*_blossom_data)[subblossoms[id]].pred = pred;
1547 1566

	
1548 1567
      } else {
1549 1568

	
1550 1569
        for (int i = (ib + 1) % subblossoms.size();
1551 1570
             i != id; i = (i + 2) % subblossoms.size()) {
1552 1571
          int sb = subblossoms[i];
1553 1572
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1554 1573
          (*_blossom_data)[sb].next =
1555 1574
            _graph.oppositeArc((*_blossom_data)[tb].next);
1556 1575
        }
1557 1576

	
1558 1577
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
1559 1578
          int sb = subblossoms[i];
1560 1579
          int tb = subblossoms[(i + 1) % subblossoms.size()];
1561 1580
          int ub = subblossoms[(i + 2) % subblossoms.size()];
1562 1581

	
1563 1582
          (*_blossom_data)[sb].status = ODD;
1564 1583
          matchedToOdd(sb);
1565 1584
          _tree_set->insert(sb, tree);
1566 1585
          (*_blossom_data)[sb].next = next;
1567 1586
          (*_blossom_data)[sb].pred =
1568 1587
            _graph.oppositeArc((*_blossom_data)[tb].next);
1569 1588

	
1570 1589
          (*_blossom_data)[tb].status = EVEN;
1571 1590
          matchedToEven(tb, tree);
1572 1591
          _tree_set->insert(tb, tree);
1573 1592
          (*_blossom_data)[tb].pred =
1574 1593
            (*_blossom_data)[tb].next =
1575 1594
            _graph.oppositeArc((*_blossom_data)[ub].next);
1576 1595
          next = (*_blossom_data)[ub].next;
1577 1596
        }
1578 1597

	
1579 1598
        (*_blossom_data)[subblossoms[ib]].status = ODD;
1580 1599
        matchedToOdd(subblossoms[ib]);
1581 1600
        _tree_set->insert(subblossoms[ib], tree);
1582 1601
        (*_blossom_data)[subblossoms[ib]].next = next;
1583 1602
        (*_blossom_data)[subblossoms[ib]].pred = pred;
1584 1603
      }
1585 1604
      _tree_set->erase(blossom);
1586 1605
    }
1587 1606

	
1588 1607
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
1589 1608
      if (_blossom_set->trivial(blossom)) {
1590 1609
        int bi = (*_node_index)[base];
1591 1610
        Value pot = (*_node_data)[bi].pot;
1592 1611

	
1593 1612
        (*_matching)[base] = matching;
1594 1613
        _blossom_node_list.push_back(base);
1595 1614
        (*_node_potential)[base] = pot;
1596 1615
      } else {
1597 1616

	
1598 1617
        Value pot = (*_blossom_data)[blossom].pot;
1599 1618
        int bn = _blossom_node_list.size();
1600 1619

	
1601 1620
        std::vector<int> subblossoms;
1602 1621
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
1603 1622
        int b = _blossom_set->find(base);
1604 1623
        int ib = -1;
1605 1624
        for (int i = 0; i < int(subblossoms.size()); ++i) {
1606 1625
          if (subblossoms[i] == b) { ib = i; break; }
1607 1626
        }
1608 1627

	
1609 1628
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
1610 1629
          int sb = subblossoms[(ib + i) % subblossoms.size()];
1611 1630
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
1612 1631

	
1613 1632
          Arc m = (*_blossom_data)[tb].next;
1614 1633
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
1615 1634
          extractBlossom(tb, _graph.source(m), m);
1616 1635
        }
1617 1636
        extractBlossom(subblossoms[ib], base, matching);
1618 1637

	
1619 1638
        int en = _blossom_node_list.size();
1620 1639

	
1621 1640
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
1622 1641
      }
1623 1642
    }
1624 1643

	
1625 1644
    void extractMatching() {
1626 1645
      std::vector<int> blossoms;
1627 1646
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
1628 1647
        blossoms.push_back(c);
1629 1648
      }
1630 1649

	
1631 1650
      for (int i = 0; i < int(blossoms.size()); ++i) {
1632 1651
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
1633 1652

	
1634 1653
          Value offset = (*_blossom_data)[blossoms[i]].offset;
1635 1654
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
1636 1655
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
1637 1656
               n != INVALID; ++n) {
1638 1657
            (*_node_data)[(*_node_index)[n]].pot -= offset;
1639 1658
          }
1640 1659

	
1641 1660
          Arc matching = (*_blossom_data)[blossoms[i]].next;
1642 1661
          Node base = _graph.source(matching);
1643 1662
          extractBlossom(blossoms[i], base, matching);
1644 1663
        } else {
1645 1664
          Node base = (*_blossom_data)[blossoms[i]].base;
1646 1665
          extractBlossom(blossoms[i], base, INVALID);
1647 1666
        }
1648 1667
      }
1649 1668
    }
1650 1669

	
1651 1670
  public:
1652 1671

	
1653 1672
    /// \brief Constructor
1654 1673
    ///
1655 1674
    /// Constructor.
1656 1675
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
1657 1676
      : _graph(graph), _weight(weight), _matching(0),
1658 1677
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
1659 1678
        _node_num(0), _blossom_num(0),
1660 1679

	
1661 1680
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
1662 1681
        _node_index(0), _node_heap_index(0), _node_data(0),
1663 1682
        _tree_set_index(0), _tree_set(0),
1664 1683

	
1665 1684
        _delta1_index(0), _delta1(0),
1666 1685
        _delta2_index(0), _delta2(0),
1667 1686
        _delta3_index(0), _delta3(0),
1668 1687
        _delta4_index(0), _delta4(0),
1669 1688

	
1670 1689
        _delta_sum() {}
1671 1690

	
1672 1691
    ~MaxWeightedMatching() {
1673 1692
      destroyStructures();
1674 1693
    }
1675 1694

	
1676 1695
    /// \name Execution Control
1677 1696
    /// The simplest way to execute the algorithm is to use the
1678 1697
    /// \ref run() member function.
1679 1698

	
1680 1699
    ///@{
1681 1700

	
1682 1701
    /// \brief Initialize the algorithm
1683 1702
    ///
1684 1703
    /// This function initializes the algorithm.
1685 1704
    void init() {
1686 1705
      createStructures();
1687 1706

	
1707
      _blossom_node_list.clear();
1708
      _blossom_potential.clear();
1709

	
1688 1710
      for (ArcIt e(_graph); e != INVALID; ++e) {
1689 1711
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
1690 1712
      }
1691 1713
      for (NodeIt n(_graph); n != INVALID; ++n) {
1692 1714
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
1693 1715
      }
1694 1716
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1695 1717
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
1696 1718
      }
1697 1719
      for (int i = 0; i < _blossom_num; ++i) {
1698 1720
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
1699 1721
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
1700 1722
      }
1723
      
1724
      _delta1->clear();
1725
      _delta2->clear();
1726
      _delta3->clear();
1727
      _delta4->clear();
1728
      _blossom_set->clear();
1729
      _tree_set->clear();
1701 1730

	
1702 1731
      int index = 0;
1703 1732
      for (NodeIt n(_graph); n != INVALID; ++n) {
1704 1733
        Value max = 0;
1705 1734
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
1706 1735
          if (_graph.target(e) == n) continue;
1707 1736
          if ((dualScale * _weight[e]) / 2 > max) {
1708 1737
            max = (dualScale * _weight[e]) / 2;
1709 1738
          }
1710 1739
        }
1711 1740
        (*_node_index)[n] = index;
1741
        (*_node_data)[index].heap_index.clear();
1742
        (*_node_data)[index].heap.clear();
1712 1743
        (*_node_data)[index].pot = max;
1713 1744
        _delta1->push(n, max);
1714 1745
        int blossom =
1715 1746
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
1716 1747

	
1717 1748
        _tree_set->insert(blossom);
1718 1749

	
1719 1750
        (*_blossom_data)[blossom].status = EVEN;
1720 1751
        (*_blossom_data)[blossom].pred = INVALID;
1721 1752
        (*_blossom_data)[blossom].next = INVALID;
1722 1753
        (*_blossom_data)[blossom].pot = 0;
1723 1754
        (*_blossom_data)[blossom].offset = 0;
1724 1755
        ++index;
1725 1756
      }
1726 1757
      for (EdgeIt e(_graph); e != INVALID; ++e) {
1727 1758
        int si = (*_node_index)[_graph.u(e)];
1728 1759
        int ti = (*_node_index)[_graph.v(e)];
1729 1760
        if (_graph.u(e) != _graph.v(e)) {
1730 1761
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
1731 1762
                            dualScale * _weight[e]) / 2);
1732 1763
        }
1733 1764
      }
1734 1765
    }
1735 1766

	
1736 1767
    /// \brief Start the algorithm
1737 1768
    ///
1738 1769
    /// This function starts the algorithm.
1739 1770
    ///
1740 1771
    /// \pre \ref init() must be called before using this function.
1741 1772
    void start() {
1742 1773
      enum OpType {
1743 1774
        D1, D2, D3, D4
1744 1775
      };
1745 1776

	
1746 1777
      int unmatched = _node_num;
1747 1778
      while (unmatched > 0) {
1748 1779
        Value d1 = !_delta1->empty() ?
1749 1780
          _delta1->prio() : std::numeric_limits<Value>::max();
1750 1781

	
1751 1782
        Value d2 = !_delta2->empty() ?
1752 1783
          _delta2->prio() : std::numeric_limits<Value>::max();
1753 1784

	
1754 1785
        Value d3 = !_delta3->empty() ?
1755 1786
          _delta3->prio() : std::numeric_limits<Value>::max();
1756 1787

	
1757 1788
        Value d4 = !_delta4->empty() ?
1758 1789
          _delta4->prio() : std::numeric_limits<Value>::max();
1759 1790

	
1760 1791
        _delta_sum = d1; OpType ot = D1;
1761 1792
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
1762 1793
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
1763 1794
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
1764 1795

	
1765 1796

	
1766 1797
        switch (ot) {
1767 1798
        case D1:
1768 1799
          {
1769 1800
            Node n = _delta1->top();
1770 1801
            unmatchNode(n);
1771 1802
            --unmatched;
1772 1803
          }
1773 1804
          break;
1774 1805
        case D2:
1775 1806
          {
1776 1807
            int blossom = _delta2->top();
1777 1808
            Node n = _blossom_set->classTop(blossom);
1778 1809
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
1779 1810
            extendOnArc(e);
1780 1811
          }
1781 1812
          break;
1782 1813
        case D3:
1783 1814
          {
1784 1815
            Edge e = _delta3->top();
1785 1816

	
1786 1817
            int left_blossom = _blossom_set->find(_graph.u(e));
1787 1818
            int right_blossom = _blossom_set->find(_graph.v(e));
1788 1819

	
1789 1820
            if (left_blossom == right_blossom) {
1790 1821
              _delta3->pop();
1791 1822
            } else {
1792 1823
              int left_tree;
1793 1824
              if ((*_blossom_data)[left_blossom].status == EVEN) {
1794 1825
                left_tree = _tree_set->find(left_blossom);
1795 1826
              } else {
1796 1827
                left_tree = -1;
1797 1828
                ++unmatched;
1798 1829
              }
1799 1830
              int right_tree;
1800 1831
              if ((*_blossom_data)[right_blossom].status == EVEN) {
1801 1832
                right_tree = _tree_set->find(right_blossom);
1802 1833
              } else {
1803 1834
                right_tree = -1;
1804 1835
                ++unmatched;
1805 1836
              }
1806 1837

	
1807 1838
              if (left_tree == right_tree) {
1808 1839
                shrinkOnEdge(e, left_tree);
1809 1840
              } else {
1810 1841
                augmentOnEdge(e);
1811 1842
                unmatched -= 2;
1812 1843
              }
1813 1844
            }
1814 1845
          } break;
1815 1846
        case D4:
1816 1847
          splitBlossom(_delta4->top());
1817 1848
          break;
1818 1849
        }
1819 1850
      }
1820 1851
      extractMatching();
1821 1852
    }
1822 1853

	
1823 1854
    /// \brief Run the algorithm.
1824 1855
    ///
1825 1856
    /// This method runs the \c %MaxWeightedMatching algorithm.
1826 1857
    ///
1827 1858
    /// \note mwm.run() is just a shortcut of the following code.
1828 1859
    /// \code
1829 1860
    ///   mwm.init();
1830 1861
    ///   mwm.start();
1831 1862
    /// \endcode
1832 1863
    void run() {
1833 1864
      init();
1834 1865
      start();
1835 1866
    }
1836 1867

	
1837 1868
    /// @}
1838 1869

	
1839 1870
    /// \name Primal Solution
1840 1871
    /// Functions to get the primal solution, i.e. the maximum weighted 
1841 1872
    /// matching.\n
1842 1873
    /// Either \ref run() or \ref start() function should be called before
1843 1874
    /// using them.
1844 1875

	
1845 1876
    /// @{
1846 1877

	
1847 1878
    /// \brief Return the weight of the matching.
1848 1879
    ///
1849 1880
    /// This function returns the weight of the found matching.
1850 1881
    ///
1851 1882
    /// \pre Either run() or start() must be called before using this function.
1852 1883
    Value matchingWeight() const {
1853 1884
      Value sum = 0;
1854 1885
      for (NodeIt n(_graph); n != INVALID; ++n) {
1855 1886
        if ((*_matching)[n] != INVALID) {
1856 1887
          sum += _weight[(*_matching)[n]];
1857 1888
        }
1858 1889
      }
1859 1890
      return sum /= 2;
1860 1891
    }
1861 1892

	
1862 1893
    /// \brief Return the size (cardinality) of the matching.
1863 1894
    ///
1864 1895
    /// This function returns the size (cardinality) of the found matching.
1865 1896
    ///
1866 1897
    /// \pre Either run() or start() must be called before using this function.
1867 1898
    int matchingSize() const {
1868 1899
      int num = 0;
1869 1900
      for (NodeIt n(_graph); n != INVALID; ++n) {
1870 1901
        if ((*_matching)[n] != INVALID) {
1871 1902
          ++num;
1872 1903
        }
1873 1904
      }
1874 1905
      return num /= 2;
1875 1906
    }
1876 1907

	
1877 1908
    /// \brief Return \c true if the given edge is in the matching.
1878 1909
    ///
1879 1910
    /// This function returns \c true if the given edge is in the found 
1880 1911
    /// matching.
1881 1912
    ///
1882 1913
    /// \pre Either run() or start() must be called before using this function.
1883 1914
    bool matching(const Edge& edge) const {
1884 1915
      return edge == (*_matching)[_graph.u(edge)];
1885 1916
    }
1886 1917

	
1887 1918
    /// \brief Return the matching arc (or edge) incident to the given node.
1888 1919
    ///
1889 1920
    /// This function returns the matching arc (or edge) incident to the
1890 1921
    /// given node in the found matching or \c INVALID if the node is 
1891 1922
    /// not covered by the matching.
1892 1923
    ///
1893 1924
    /// \pre Either run() or start() must be called before using this function.
1894 1925
    Arc matching(const Node& node) const {
1895 1926
      return (*_matching)[node];
1896 1927
    }
1897 1928

	
1898 1929
    /// \brief Return a const reference to the matching map.
1899 1930
    ///
1900 1931
    /// This function returns a const reference to a node map that stores
1901 1932
    /// the matching arc (or edge) incident to each node.
1902 1933
    const MatchingMap& matchingMap() const {
1903 1934
      return *_matching;
1904 1935
    }
1905 1936

	
1906 1937
    /// \brief Return the mate of the given node.
1907 1938
    ///
1908 1939
    /// This function returns the mate of the given node in the found 
1909 1940
    /// matching or \c INVALID if the node is not covered by the matching.
1910 1941
    ///
1911 1942
    /// \pre Either run() or start() must be called before using this function.
1912 1943
    Node mate(const Node& node) const {
1913 1944
      return (*_matching)[node] != INVALID ?
1914 1945
        _graph.target((*_matching)[node]) : INVALID;
1915 1946
    }
1916 1947

	
1917 1948
    /// @}
1918 1949

	
1919 1950
    /// \name Dual Solution
1920 1951
    /// Functions to get the dual solution.\n
1921 1952
    /// Either \ref run() or \ref start() function should be called before
1922 1953
    /// using them.
1923 1954

	
1924 1955
    /// @{
1925 1956

	
1926 1957
    /// \brief Return the value of the dual solution.
1927 1958
    ///
1928 1959
    /// This function returns the value of the dual solution. 
1929 1960
    /// It should be equal to the primal value scaled by \ref dualScale 
1930 1961
    /// "dual scale".
1931 1962
    ///
1932 1963
    /// \pre Either run() or start() must be called before using this function.
1933 1964
    Value dualValue() const {
1934 1965
      Value sum = 0;
1935 1966
      for (NodeIt n(_graph); n != INVALID; ++n) {
1936 1967
        sum += nodeValue(n);
1937 1968
      }
1938 1969
      for (int i = 0; i < blossomNum(); ++i) {
1939 1970
        sum += blossomValue(i) * (blossomSize(i) / 2);
1940 1971
      }
1941 1972
      return sum;
1942 1973
    }
1943 1974

	
1944 1975
    /// \brief Return the dual value (potential) of the given node.
1945 1976
    ///
1946 1977
    /// This function returns the dual value (potential) of the given node.
1947 1978
    ///
1948 1979
    /// \pre Either run() or start() must be called before using this function.
1949 1980
    Value nodeValue(const Node& n) const {
1950 1981
      return (*_node_potential)[n];
1951 1982
    }
1952 1983

	
1953 1984
    /// \brief Return the number of the blossoms in the basis.
1954 1985
    ///
1955 1986
    /// This function returns the number of the blossoms in the basis.
1956 1987
    ///
1957 1988
    /// \pre Either run() or start() must be called before using this function.
1958 1989
    /// \see BlossomIt
1959 1990
    int blossomNum() const {
1960 1991
      return _blossom_potential.size();
1961 1992
    }
1962 1993

	
1963 1994
    /// \brief Return the number of the nodes in the given blossom.
1964 1995
    ///
1965 1996
    /// This function returns the number of the nodes in the given blossom.
1966 1997
    ///
1967 1998
    /// \pre Either run() or start() must be called before using this function.
1968 1999
    /// \see BlossomIt
1969 2000
    int blossomSize(int k) const {
1970 2001
      return _blossom_potential[k].end - _blossom_potential[k].begin;
1971 2002
    }
1972 2003

	
1973 2004
    /// \brief Return the dual value (ptential) of the given blossom.
1974 2005
    ///
1975 2006
    /// This function returns the dual value (ptential) of the given blossom.
1976 2007
    ///
1977 2008
    /// \pre Either run() or start() must be called before using this function.
1978 2009
    Value blossomValue(int k) const {
1979 2010
      return _blossom_potential[k].value;
1980 2011
    }
1981 2012

	
1982 2013
    /// \brief Iterator for obtaining the nodes of a blossom.
1983 2014
    ///
1984 2015
    /// This class provides an iterator for obtaining the nodes of the 
1985 2016
    /// given blossom. It lists a subset of the nodes.
1986 2017
    /// Before using this iterator, you must allocate a 
1987 2018
    /// MaxWeightedMatching class and execute it.
1988 2019
    class BlossomIt {
1989 2020
    public:
1990 2021

	
1991 2022
      /// \brief Constructor.
1992 2023
      ///
1993 2024
      /// Constructor to get the nodes of the given variable.
1994 2025
      ///
1995 2026
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
1996 2027
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
1997 2028
      /// called before initializing this iterator.
1998 2029
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
1999 2030
        : _algorithm(&algorithm)
2000 2031
      {
2001 2032
        _index = _algorithm->_blossom_potential[variable].begin;
2002 2033
        _last = _algorithm->_blossom_potential[variable].end;
2003 2034
      }
2004 2035

	
2005 2036
      /// \brief Conversion to \c Node.
2006 2037
      ///
2007 2038
      /// Conversion to \c Node.
2008 2039
      operator Node() const {
2009 2040
        return _algorithm->_blossom_node_list[_index];
2010 2041
      }
2011 2042

	
2012 2043
      /// \brief Increment operator.
2013 2044
      ///
2014 2045
      /// Increment operator.
2015 2046
      BlossomIt& operator++() {
2016 2047
        ++_index;
2017 2048
        return *this;
2018 2049
      }
2019 2050

	
2020 2051
      /// \brief Validity checking
2021 2052
      ///
2022 2053
      /// Checks whether the iterator is invalid.
2023 2054
      bool operator==(Invalid) const { return _index == _last; }
2024 2055

	
2025 2056
      /// \brief Validity checking
2026 2057
      ///
2027 2058
      /// Checks whether the iterator is valid.
2028 2059
      bool operator!=(Invalid) const { return _index != _last; }
2029 2060

	
2030 2061
    private:
2031 2062
      const MaxWeightedMatching* _algorithm;
2032 2063
      int _last;
2033 2064
      int _index;
2034 2065
    };
2035 2066

	
2036 2067
    /// @}
2037 2068

	
2038 2069
  };
2039 2070

	
2040 2071
  /// \ingroup matching
2041 2072
  ///
2042 2073
  /// \brief Weighted perfect matching in general graphs
2043 2074
  ///
2044 2075
  /// This class provides an efficient implementation of Edmond's
2045 2076
  /// maximum weighted perfect matching algorithm. The implementation
2046 2077
  /// is based on extensive use of priority queues and provides
2047 2078
  /// \f$O(nm\log n)\f$ time complexity.
2048 2079
  ///
2049 2080
  /// The maximum weighted perfect matching problem is to find a subset of 
2050 2081
  /// the edges in an undirected graph with maximum overall weight for which 
2051 2082
  /// each node has exactly one incident edge.
2052 2083
  /// It can be formulated with the following linear program.
2053 2084
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
2054 2085
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
2055 2086
      \quad \forall B\in\mathcal{O}\f] */
2056 2087
  /// \f[x_e \ge 0\quad \forall e\in E\f]
2057 2088
  /// \f[\max \sum_{e\in E}x_ew_e\f]
2058 2089
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
2059 2090
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
2060 2091
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
2061 2092
  /// subsets of the nodes.
2062 2093
  ///
2063 2094
  /// The algorithm calculates an optimal matching and a proof of the
2064 2095
  /// optimality. The solution of the dual problem can be used to check
2065 2096
  /// the result of the algorithm. The dual linear problem is the
2066 2097
  /// following.
2067 2098
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
2068 2099
      w_{uv} \quad \forall uv\in E\f] */
2069 2100
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
2070 2101
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
2071 2102
      \frac{\vert B \vert - 1}{2}z_B\f] */
2072 2103
  ///
2073 2104
  /// The algorithm can be executed with the run() function. 
2074 2105
  /// After it the matching (the primal solution) and the dual solution
2075 2106
  /// can be obtained using the query functions and the 
2076 2107
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
2077 2108
  /// which is able to iterate on the nodes of a blossom. 
2078 2109
  /// If the value type is integer, then the dual solution is multiplied
2079 2110
  /// by \ref MaxWeightedMatching::dualScale "4".
2080 2111
  ///
2081 2112
  /// \tparam GR The undirected graph type the algorithm runs on.
2082 2113
  /// \tparam WM The type edge weight map. The default type is 
2083 2114
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
2084 2115
#ifdef DOXYGEN
2085 2116
  template <typename GR, typename WM>
2086 2117
#else
2087 2118
  template <typename GR,
2088 2119
            typename WM = typename GR::template EdgeMap<int> >
2089 2120
#endif
2090 2121
  class MaxWeightedPerfectMatching {
2091 2122
  public:
2092 2123

	
2093 2124
    /// The graph type of the algorithm
2094 2125
    typedef GR Graph;
2095 2126
    /// The type of the edge weight map
2096 2127
    typedef WM WeightMap;
2097 2128
    /// The value type of the edge weights
2098 2129
    typedef typename WeightMap::Value Value;
2099 2130

	
2100 2131
    /// \brief Scaling factor for dual solution
2101 2132
    ///
2102 2133
    /// Scaling factor for dual solution, it is equal to 4 or 1
2103 2134
    /// according to the value type.
2104 2135
    static const int dualScale =
2105 2136
      std::numeric_limits<Value>::is_integer ? 4 : 1;
2106 2137

	
2107 2138
    /// The type of the matching map
2108 2139
    typedef typename Graph::template NodeMap<typename Graph::Arc>
2109 2140
    MatchingMap;
2110 2141

	
2111 2142
  private:
2112 2143

	
2113 2144
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
2114 2145

	
2115 2146
    typedef typename Graph::template NodeMap<Value> NodePotential;
2116 2147
    typedef std::vector<Node> BlossomNodeList;
2117 2148

	
2118 2149
    struct BlossomVariable {
2119 2150
      int begin, end;
2120 2151
      Value value;
2121 2152

	
2122 2153
      BlossomVariable(int _begin, int _end, Value _value)
2123 2154
        : begin(_begin), end(_end), value(_value) {}
2124 2155

	
2125 2156
    };
2126 2157

	
2127 2158
    typedef std::vector<BlossomVariable> BlossomPotential;
2128 2159

	
2129 2160
    const Graph& _graph;
2130 2161
    const WeightMap& _weight;
2131 2162

	
2132 2163
    MatchingMap* _matching;
2133 2164

	
2134 2165
    NodePotential* _node_potential;
2135 2166

	
2136 2167
    BlossomPotential _blossom_potential;
2137 2168
    BlossomNodeList _blossom_node_list;
2138 2169

	
2139 2170
    int _node_num;
2140 2171
    int _blossom_num;
2141 2172

	
2142 2173
    typedef RangeMap<int> IntIntMap;
2143 2174

	
2144 2175
    enum Status {
2145 2176
      EVEN = -1, MATCHED = 0, ODD = 1
2146 2177
    };
2147 2178

	
2148 2179
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
2149 2180
    struct BlossomData {
2150 2181
      int tree;
2151 2182
      Status status;
2152 2183
      Arc pred, next;
2153 2184
      Value pot, offset;
2154 2185
    };
2155 2186

	
2156 2187
    IntNodeMap *_blossom_index;
2157 2188
    BlossomSet *_blossom_set;
2158 2189
    RangeMap<BlossomData>* _blossom_data;
2159 2190

	
2160 2191
    IntNodeMap *_node_index;
2161 2192
    IntArcMap *_node_heap_index;
2162 2193

	
2163 2194
    struct NodeData {
2164 2195

	
2165 2196
      NodeData(IntArcMap& node_heap_index)
2166 2197
        : heap(node_heap_index) {}
2167 2198

	
2168 2199
      int blossom;
2169 2200
      Value pot;
2170 2201
      BinHeap<Value, IntArcMap> heap;
2171 2202
      std::map<int, Arc> heap_index;
2172 2203

	
2173 2204
      int tree;
2174 2205
    };
2175 2206

	
2176 2207
    RangeMap<NodeData>* _node_data;
2177 2208

	
2178 2209
    typedef ExtendFindEnum<IntIntMap> TreeSet;
2179 2210

	
2180 2211
    IntIntMap *_tree_set_index;
2181 2212
    TreeSet *_tree_set;
2182 2213

	
2183 2214
    IntIntMap *_delta2_index;
2184 2215
    BinHeap<Value, IntIntMap> *_delta2;
2185 2216

	
2186 2217
    IntEdgeMap *_delta3_index;
2187 2218
    BinHeap<Value, IntEdgeMap> *_delta3;
2188 2219

	
2189 2220
    IntIntMap *_delta4_index;
2190 2221
    BinHeap<Value, IntIntMap> *_delta4;
2191 2222

	
2192 2223
    Value _delta_sum;
2193 2224

	
2194 2225
    void createStructures() {
2195 2226
      _node_num = countNodes(_graph);
2196 2227
      _blossom_num = _node_num * 3 / 2;
2197 2228

	
2198 2229
      if (!_matching) {
2199 2230
        _matching = new MatchingMap(_graph);
2200 2231
      }
2232

	
2201 2233
      if (!_node_potential) {
2202 2234
        _node_potential = new NodePotential(_graph);
2203 2235
      }
2236

	
2204 2237
      if (!_blossom_set) {
2205 2238
        _blossom_index = new IntNodeMap(_graph);
2206 2239
        _blossom_set = new BlossomSet(*_blossom_index);
2207 2240
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2241
      } else if (_blossom_data->size() != _blossom_num) {
2242
        delete _blossom_data;
2243
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
2208 2244
      }
2209 2245

	
2210 2246
      if (!_node_index) {
2211 2247
        _node_index = new IntNodeMap(_graph);
2212 2248
        _node_heap_index = new IntArcMap(_graph);
2213 2249
        _node_data = new RangeMap<NodeData>(_node_num,
2214 2250
                                            NodeData(*_node_heap_index));
2251
      } else if (_node_data->size() != _node_num) {
2252
        delete _node_data;
2253
        _node_data = new RangeMap<NodeData>(_node_num,
2254
                                            NodeData(*_node_heap_index));
2215 2255
      }
2216 2256

	
2217 2257
      if (!_tree_set) {
2218 2258
        _tree_set_index = new IntIntMap(_blossom_num);
2219 2259
        _tree_set = new TreeSet(*_tree_set_index);
2260
      } else {
2261
        _tree_set_index->resize(_blossom_num);
2220 2262
      }
2263

	
2221 2264
      if (!_delta2) {
2222 2265
        _delta2_index = new IntIntMap(_blossom_num);
2223 2266
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
2267
      } else {
2268
        _delta2_index->resize(_blossom_num);
2224 2269
      }
2270

	
2225 2271
      if (!_delta3) {
2226 2272
        _delta3_index = new IntEdgeMap(_graph);
2227 2273
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
2228 2274
      }
2275

	
2229 2276
      if (!_delta4) {
2230 2277
        _delta4_index = new IntIntMap(_blossom_num);
2231 2278
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
2279
      } else {
2280
        _delta4_index->resize(_blossom_num);
2232 2281
      }
2233 2282
    }
2234 2283

	
2235 2284
    void destroyStructures() {
2236 2285
      _node_num = countNodes(_graph);
2237 2286
      _blossom_num = _node_num * 3 / 2;
2238 2287

	
2239 2288
      if (_matching) {
2240 2289
        delete _matching;
2241 2290
      }
2242 2291
      if (_node_potential) {
2243 2292
        delete _node_potential;
2244 2293
      }
2245 2294
      if (_blossom_set) {
2246 2295
        delete _blossom_index;
2247 2296
        delete _blossom_set;
2248 2297
        delete _blossom_data;
2249 2298
      }
2250 2299

	
2251 2300
      if (_node_index) {
2252 2301
        delete _node_index;
2253 2302
        delete _node_heap_index;
2254 2303
        delete _node_data;
2255 2304
      }
2256 2305

	
2257 2306
      if (_tree_set) {
2258 2307
        delete _tree_set_index;
2259 2308
        delete _tree_set;
2260 2309
      }
2261 2310
      if (_delta2) {
2262 2311
        delete _delta2_index;
2263 2312
        delete _delta2;
2264 2313
      }
2265 2314
      if (_delta3) {
2266 2315
        delete _delta3_index;
2267 2316
        delete _delta3;
2268 2317
      }
2269 2318
      if (_delta4) {
2270 2319
        delete _delta4_index;
2271 2320
        delete _delta4;
2272 2321
      }
2273 2322
    }
2274 2323

	
2275 2324
    void matchedToEven(int blossom, int tree) {
2276 2325
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2277 2326
        _delta2->erase(blossom);
2278 2327
      }
2279 2328

	
2280 2329
      if (!_blossom_set->trivial(blossom)) {
2281 2330
        (*_blossom_data)[blossom].pot -=
2282 2331
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
2283 2332
      }
2284 2333

	
2285 2334
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2286 2335
           n != INVALID; ++n) {
2287 2336

	
2288 2337
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2289 2338
        int ni = (*_node_index)[n];
2290 2339

	
2291 2340
        (*_node_data)[ni].heap.clear();
2292 2341
        (*_node_data)[ni].heap_index.clear();
2293 2342

	
2294 2343
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
2295 2344

	
2296 2345
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2297 2346
          Node v = _graph.source(e);
2298 2347
          int vb = _blossom_set->find(v);
2299 2348
          int vi = (*_node_index)[v];
2300 2349

	
2301 2350
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2302 2351
            dualScale * _weight[e];
2303 2352

	
2304 2353
          if ((*_blossom_data)[vb].status == EVEN) {
2305 2354
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2306 2355
              _delta3->push(e, rw / 2);
2307 2356
            }
2308 2357
          } else {
2309 2358
            typename std::map<int, Arc>::iterator it =
2310 2359
              (*_node_data)[vi].heap_index.find(tree);
2311 2360

	
2312 2361
            if (it != (*_node_data)[vi].heap_index.end()) {
2313 2362
              if ((*_node_data)[vi].heap[it->second] > rw) {
2314 2363
                (*_node_data)[vi].heap.replace(it->second, e);
2315 2364
                (*_node_data)[vi].heap.decrease(e, rw);
2316 2365
                it->second = e;
2317 2366
              }
2318 2367
            } else {
2319 2368
              (*_node_data)[vi].heap.push(e, rw);
2320 2369
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2321 2370
            }
2322 2371

	
2323 2372
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2324 2373
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2325 2374

	
2326 2375
              if ((*_blossom_data)[vb].status == MATCHED) {
2327 2376
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2328 2377
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2329 2378
                               (*_blossom_data)[vb].offset);
2330 2379
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2331 2380
                           (*_blossom_data)[vb].offset){
2332 2381
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2333 2382
                                   (*_blossom_data)[vb].offset);
2334 2383
                }
2335 2384
              }
2336 2385
            }
2337 2386
          }
2338 2387
        }
2339 2388
      }
2340 2389
      (*_blossom_data)[blossom].offset = 0;
2341 2390
    }
2342 2391

	
2343 2392
    void matchedToOdd(int blossom) {
2344 2393
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2345 2394
        _delta2->erase(blossom);
2346 2395
      }
2347 2396
      (*_blossom_data)[blossom].offset += _delta_sum;
2348 2397
      if (!_blossom_set->trivial(blossom)) {
2349 2398
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
2350 2399
                     (*_blossom_data)[blossom].offset);
2351 2400
      }
2352 2401
    }
2353 2402

	
2354 2403
    void evenToMatched(int blossom, int tree) {
2355 2404
      if (!_blossom_set->trivial(blossom)) {
2356 2405
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
2357 2406
      }
2358 2407

	
2359 2408
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2360 2409
           n != INVALID; ++n) {
2361 2410
        int ni = (*_node_index)[n];
2362 2411
        (*_node_data)[ni].pot -= _delta_sum;
2363 2412

	
2364 2413
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2365 2414
          Node v = _graph.source(e);
2366 2415
          int vb = _blossom_set->find(v);
2367 2416
          int vi = (*_node_index)[v];
2368 2417

	
2369 2418
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2370 2419
            dualScale * _weight[e];
2371 2420

	
2372 2421
          if (vb == blossom) {
2373 2422
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2374 2423
              _delta3->erase(e);
2375 2424
            }
2376 2425
          } else if ((*_blossom_data)[vb].status == EVEN) {
2377 2426

	
2378 2427
            if (_delta3->state(e) == _delta3->IN_HEAP) {
2379 2428
              _delta3->erase(e);
2380 2429
            }
2381 2430

	
2382 2431
            int vt = _tree_set->find(vb);
2383 2432

	
2384 2433
            if (vt != tree) {
2385 2434

	
2386 2435
              Arc r = _graph.oppositeArc(e);
2387 2436

	
2388 2437
              typename std::map<int, Arc>::iterator it =
2389 2438
                (*_node_data)[ni].heap_index.find(vt);
2390 2439

	
2391 2440
              if (it != (*_node_data)[ni].heap_index.end()) {
2392 2441
                if ((*_node_data)[ni].heap[it->second] > rw) {
2393 2442
                  (*_node_data)[ni].heap.replace(it->second, r);
2394 2443
                  (*_node_data)[ni].heap.decrease(r, rw);
2395 2444
                  it->second = r;
2396 2445
                }
2397 2446
              } else {
2398 2447
                (*_node_data)[ni].heap.push(r, rw);
2399 2448
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
2400 2449
              }
2401 2450

	
2402 2451
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
2403 2452
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
2404 2453

	
2405 2454
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
2406 2455
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2407 2456
                               (*_blossom_data)[blossom].offset);
2408 2457
                } else if ((*_delta2)[blossom] >
2409 2458
                           _blossom_set->classPrio(blossom) -
2410 2459
                           (*_blossom_data)[blossom].offset){
2411 2460
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
2412 2461
                                   (*_blossom_data)[blossom].offset);
2413 2462
                }
2414 2463
              }
2415 2464
            }
2416 2465
          } else {
2417 2466

	
2418 2467
            typename std::map<int, Arc>::iterator it =
2419 2468
              (*_node_data)[vi].heap_index.find(tree);
2420 2469

	
2421 2470
            if (it != (*_node_data)[vi].heap_index.end()) {
2422 2471
              (*_node_data)[vi].heap.erase(it->second);
2423 2472
              (*_node_data)[vi].heap_index.erase(it);
2424 2473
              if ((*_node_data)[vi].heap.empty()) {
2425 2474
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
2426 2475
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
2427 2476
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
2428 2477
              }
2429 2478

	
2430 2479
              if ((*_blossom_data)[vb].status == MATCHED) {
2431 2480
                if (_blossom_set->classPrio(vb) ==
2432 2481
                    std::numeric_limits<Value>::max()) {
2433 2482
                  _delta2->erase(vb);
2434 2483
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
2435 2484
                           (*_blossom_data)[vb].offset) {
2436 2485
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
2437 2486
                                   (*_blossom_data)[vb].offset);
2438 2487
                }
2439 2488
              }
2440 2489
            }
2441 2490
          }
2442 2491
        }
2443 2492
      }
2444 2493
    }
2445 2494

	
2446 2495
    void oddToMatched(int blossom) {
2447 2496
      (*_blossom_data)[blossom].offset -= _delta_sum;
2448 2497

	
2449 2498
      if (_blossom_set->classPrio(blossom) !=
2450 2499
          std::numeric_limits<Value>::max()) {
2451 2500
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
2452 2501
                       (*_blossom_data)[blossom].offset);
2453 2502
      }
2454 2503

	
2455 2504
      if (!_blossom_set->trivial(blossom)) {
2456 2505
        _delta4->erase(blossom);
2457 2506
      }
2458 2507
    }
2459 2508

	
2460 2509
    void oddToEven(int blossom, int tree) {
2461 2510
      if (!_blossom_set->trivial(blossom)) {
2462 2511
        _delta4->erase(blossom);
2463 2512
        (*_blossom_data)[blossom].pot -=
2464 2513
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
2465 2514
      }
2466 2515

	
2467 2516
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
2468 2517
           n != INVALID; ++n) {
2469 2518
        int ni = (*_node_index)[n];
2470 2519

	
2471 2520
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
2472 2521

	
2473 2522
        (*_node_data)[ni].heap.clear();
2474 2523
        (*_node_data)[ni].heap_index.clear();
2475 2524
        (*_node_data)[ni].pot +=
2476 2525
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
2477 2526

	
2478 2527
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
2479 2528
          Node v = _graph.source(e);
2480 2529
          int vb = _blossom_set->find(v);
2481 2530
          int vi = (*_node_index)[v];
2482 2531

	
2483 2532
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
2484 2533
            dualScale * _weight[e];
2485 2534

	
2486 2535
          if ((*_blossom_data)[vb].status == EVEN) {
2487 2536
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
2488 2537
              _delta3->push(e, rw / 2);
2489 2538
            }
2490 2539
          } else {
2491 2540

	
2492 2541
            typename std::map<int, Arc>::iterator it =
2493 2542
              (*_node_data)[vi].heap_index.find(tree);
2494 2543

	
2495 2544
            if (it != (*_node_data)[vi].heap_index.end()) {
2496 2545
              if ((*_node_data)[vi].heap[it->second] > rw) {
2497 2546
                (*_node_data)[vi].heap.replace(it->second, e);
2498 2547
                (*_node_data)[vi].heap.decrease(e, rw);
2499 2548
                it->second = e;
2500 2549
              }
2501 2550
            } else {
2502 2551
              (*_node_data)[vi].heap.push(e, rw);
2503 2552
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
2504 2553
            }
2505 2554

	
2506 2555
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
2507 2556
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
2508 2557

	
2509 2558
              if ((*_blossom_data)[vb].status == MATCHED) {
2510 2559
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
2511 2560
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
2512 2561
                               (*_blossom_data)[vb].offset);
2513 2562
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
2514 2563
                           (*_blossom_data)[vb].offset) {
2515 2564
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
2516 2565
                                   (*_blossom_data)[vb].offset);
2517 2566
                }
2518 2567
              }
2519 2568
            }
2520 2569
          }
2521 2570
        }
2522 2571
      }
2523 2572
      (*_blossom_data)[blossom].offset = 0;
2524 2573
    }
2525 2574

	
2526 2575
    void alternatePath(int even, int tree) {
2527 2576
      int odd;
2528 2577

	
2529 2578
      evenToMatched(even, tree);
2530 2579
      (*_blossom_data)[even].status = MATCHED;
2531 2580

	
2532 2581
      while ((*_blossom_data)[even].pred != INVALID) {
2533 2582
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
2534 2583
        (*_blossom_data)[odd].status = MATCHED;
2535 2584
        oddToMatched(odd);
2536 2585
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
2537 2586

	
2538 2587
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
2539 2588
        (*_blossom_data)[even].status = MATCHED;
2540 2589
        evenToMatched(even, tree);
2541 2590
        (*_blossom_data)[even].next =
2542 2591
          _graph.oppositeArc((*_blossom_data)[odd].pred);
2543 2592
      }
2544 2593

	
2545 2594
    }
2546 2595

	
2547 2596
    void destroyTree(int tree) {
2548 2597
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
2549 2598
        if ((*_blossom_data)[b].status == EVEN) {
2550 2599
          (*_blossom_data)[b].status = MATCHED;
2551 2600
          evenToMatched(b, tree);
2552 2601
        } else if ((*_blossom_data)[b].status == ODD) {
2553 2602
          (*_blossom_data)[b].status = MATCHED;
2554 2603
          oddToMatched(b);
2555 2604
        }
2556 2605
      }
2557 2606
      _tree_set->eraseClass(tree);
2558 2607
    }
2559 2608

	
2560 2609
    void augmentOnEdge(const Edge& edge) {
2561 2610

	
2562 2611
      int left = _blossom_set->find(_graph.u(edge));
2563 2612
      int right = _blossom_set->find(_graph.v(edge));
2564 2613

	
2565 2614
      int left_tree = _tree_set->find(left);
2566 2615
      alternatePath(left, left_tree);
2567 2616
      destroyTree(left_tree);
2568 2617

	
2569 2618
      int right_tree = _tree_set->find(right);
2570 2619
      alternatePath(right, right_tree);
2571 2620
      destroyTree(right_tree);
2572 2621

	
2573 2622
      (*_blossom_data)[left].next = _graph.direct(edge, true);
2574 2623
      (*_blossom_data)[right].next = _graph.direct(edge, false);
2575 2624
    }
2576 2625

	
2577 2626
    void extendOnArc(const Arc& arc) {
2578 2627
      int base = _blossom_set->find(_graph.target(arc));
2579 2628
      int tree = _tree_set->find(base);
2580 2629

	
2581 2630
      int odd = _blossom_set->find(_graph.source(arc));
2582 2631
      _tree_set->insert(odd, tree);
2583 2632
      (*_blossom_data)[odd].status = ODD;
2584 2633
      matchedToOdd(odd);
2585 2634
      (*_blossom_data)[odd].pred = arc;
2586 2635

	
2587 2636
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
2588 2637
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
2589 2638
      _tree_set->insert(even, tree);
2590 2639
      (*_blossom_data)[even].status = EVEN;
2591 2640
      matchedToEven(even, tree);
2592 2641
    }
2593 2642

	
2594 2643
    void shrinkOnEdge(const Edge& edge, int tree) {
2595 2644
      int nca = -1;
2596 2645
      std::vector<int> left_path, right_path;
2597 2646

	
2598 2647
      {
2599 2648
        std::set<int> left_set, right_set;
2600 2649
        int left = _blossom_set->find(_graph.u(edge));
2601 2650
        left_path.push_back(left);
2602 2651
        left_set.insert(left);
2603 2652

	
2604 2653
        int right = _blossom_set->find(_graph.v(edge));
2605 2654
        right_path.push_back(right);
2606 2655
        right_set.insert(right);
2607 2656

	
2608 2657
        while (true) {
2609 2658

	
2610 2659
          if ((*_blossom_data)[left].pred == INVALID) break;
2611 2660

	
2612 2661
          left =
2613 2662
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2614 2663
          left_path.push_back(left);
2615 2664
          left =
2616 2665
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
2617 2666
          left_path.push_back(left);
2618 2667

	
2619 2668
          left_set.insert(left);
2620 2669

	
2621 2670
          if (right_set.find(left) != right_set.end()) {
2622 2671
            nca = left;
2623 2672
            break;
2624 2673
          }
2625 2674

	
2626 2675
          if ((*_blossom_data)[right].pred == INVALID) break;
2627 2676

	
2628 2677
          right =
2629 2678
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2630 2679
          right_path.push_back(right);
2631 2680
          right =
2632 2681
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
2633 2682
          right_path.push_back(right);
2634 2683

	
2635 2684
          right_set.insert(right);
2636 2685

	
2637 2686
          if (left_set.find(right) != left_set.end()) {
2638 2687
            nca = right;
2639 2688
            break;
2640 2689
          }
2641 2690

	
2642 2691
        }
2643 2692

	
2644 2693
        if (nca == -1) {
2645 2694
          if ((*_blossom_data)[left].pred == INVALID) {
2646 2695
            nca = right;
2647 2696
            while (left_set.find(nca) == left_set.end()) {
2648 2697
              nca =
2649 2698
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2650 2699
              right_path.push_back(nca);
2651 2700
              nca =
2652 2701
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2653 2702
              right_path.push_back(nca);
2654 2703
            }
2655 2704
          } else {
2656 2705
            nca = left;
2657 2706
            while (right_set.find(nca) == right_set.end()) {
2658 2707
              nca =
2659 2708
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2660 2709
              left_path.push_back(nca);
2661 2710
              nca =
2662 2711
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
2663 2712
              left_path.push_back(nca);
2664 2713
            }
2665 2714
          }
2666 2715
        }
2667 2716
      }
2668 2717

	
2669 2718
      std::vector<int> subblossoms;
2670 2719
      Arc prev;
2671 2720

	
2672 2721
      prev = _graph.direct(edge, true);
2673 2722
      for (int i = 0; left_path[i] != nca; i += 2) {
2674 2723
        subblossoms.push_back(left_path[i]);
2675 2724
        (*_blossom_data)[left_path[i]].next = prev;
2676 2725
        _tree_set->erase(left_path[i]);
2677 2726

	
2678 2727
        subblossoms.push_back(left_path[i + 1]);
2679 2728
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
2680 2729
        oddToEven(left_path[i + 1], tree);
2681 2730
        _tree_set->erase(left_path[i + 1]);
2682 2731
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
2683 2732
      }
2684 2733

	
2685 2734
      int k = 0;
2686 2735
      while (right_path[k] != nca) ++k;
2687 2736

	
2688 2737
      subblossoms.push_back(nca);
2689 2738
      (*_blossom_data)[nca].next = prev;
2690 2739

	
2691 2740
      for (int i = k - 2; i >= 0; i -= 2) {
2692 2741
        subblossoms.push_back(right_path[i + 1]);
2693 2742
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
2694 2743
        oddToEven(right_path[i + 1], tree);
2695 2744
        _tree_set->erase(right_path[i + 1]);
2696 2745

	
2697 2746
        (*_blossom_data)[right_path[i + 1]].next =
2698 2747
          (*_blossom_data)[right_path[i + 1]].pred;
2699 2748

	
2700 2749
        subblossoms.push_back(right_path[i]);
2701 2750
        _tree_set->erase(right_path[i]);
2702 2751
      }
2703 2752

	
2704 2753
      int surface =
2705 2754
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
2706 2755

	
2707 2756
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2708 2757
        if (!_blossom_set->trivial(subblossoms[i])) {
2709 2758
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
2710 2759
        }
2711 2760
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
2712 2761
      }
2713 2762

	
2714 2763
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
2715 2764
      (*_blossom_data)[surface].offset = 0;
2716 2765
      (*_blossom_data)[surface].status = EVEN;
2717 2766
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
2718 2767
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
2719 2768

	
2720 2769
      _tree_set->insert(surface, tree);
2721 2770
      _tree_set->erase(nca);
2722 2771
    }
2723 2772

	
2724 2773
    void splitBlossom(int blossom) {
2725 2774
      Arc next = (*_blossom_data)[blossom].next;
2726 2775
      Arc pred = (*_blossom_data)[blossom].pred;
2727 2776

	
2728 2777
      int tree = _tree_set->find(blossom);
2729 2778

	
2730 2779
      (*_blossom_data)[blossom].status = MATCHED;
2731 2780
      oddToMatched(blossom);
2732 2781
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
2733 2782
        _delta2->erase(blossom);
2734 2783
      }
2735 2784

	
2736 2785
      std::vector<int> subblossoms;
2737 2786
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
2738 2787

	
2739 2788
      Value offset = (*_blossom_data)[blossom].offset;
2740 2789
      int b = _blossom_set->find(_graph.source(pred));
2741 2790
      int d = _blossom_set->find(_graph.source(next));
2742 2791

	
2743 2792
      int ib = -1, id = -1;
2744 2793
      for (int i = 0; i < int(subblossoms.size()); ++i) {
2745 2794
        if (subblossoms[i] == b) ib = i;
2746 2795
        if (subblossoms[i] == d) id = i;
2747 2796

	
2748 2797
        (*_blossom_data)[subblossoms[i]].offset = offset;
2749 2798
        if (!_blossom_set->trivial(subblossoms[i])) {
2750 2799
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
2751 2800
        }
2752 2801
        if (_blossom_set->classPrio(subblossoms[i]) !=
2753 2802
            std::numeric_limits<Value>::max()) {
2754 2803
          _delta2->push(subblossoms[i],
2755 2804
                        _blossom_set->classPrio(subblossoms[i]) -
2756 2805
                        (*_blossom_data)[subblossoms[i]].offset);
2757 2806
        }
2758 2807
      }
2759 2808

	
2760 2809
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
2761 2810
        for (int i = (id + 1) % subblossoms.size();
2762 2811
             i != ib; i = (i + 2) % subblossoms.size()) {
2763 2812
          int sb = subblossoms[i];
2764 2813
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2765 2814
          (*_blossom_data)[sb].next =
2766 2815
            _graph.oppositeArc((*_blossom_data)[tb].next);
2767 2816
        }
2768 2817

	
2769 2818
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
2770 2819
          int sb = subblossoms[i];
2771 2820
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2772 2821
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2773 2822

	
2774 2823
          (*_blossom_data)[sb].status = ODD;
2775 2824
          matchedToOdd(sb);
2776 2825
          _tree_set->insert(sb, tree);
2777 2826
          (*_blossom_data)[sb].pred = pred;
2778 2827
          (*_blossom_data)[sb].next =
2779 2828
                           _graph.oppositeArc((*_blossom_data)[tb].next);
2780 2829

	
2781 2830
          pred = (*_blossom_data)[ub].next;
2782 2831

	
2783 2832
          (*_blossom_data)[tb].status = EVEN;
2784 2833
          matchedToEven(tb, tree);
2785 2834
          _tree_set->insert(tb, tree);
2786 2835
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
2787 2836
        }
2788 2837

	
2789 2838
        (*_blossom_data)[subblossoms[id]].status = ODD;
2790 2839
        matchedToOdd(subblossoms[id]);
2791 2840
        _tree_set->insert(subblossoms[id], tree);
2792 2841
        (*_blossom_data)[subblossoms[id]].next = next;
2793 2842
        (*_blossom_data)[subblossoms[id]].pred = pred;
2794 2843

	
2795 2844
      } else {
2796 2845

	
2797 2846
        for (int i = (ib + 1) % subblossoms.size();
2798 2847
             i != id; i = (i + 2) % subblossoms.size()) {
2799 2848
          int sb = subblossoms[i];
2800 2849
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2801 2850
          (*_blossom_data)[sb].next =
2802 2851
            _graph.oppositeArc((*_blossom_data)[tb].next);
2803 2852
        }
2804 2853

	
2805 2854
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
2806 2855
          int sb = subblossoms[i];
2807 2856
          int tb = subblossoms[(i + 1) % subblossoms.size()];
2808 2857
          int ub = subblossoms[(i + 2) % subblossoms.size()];
2809 2858

	
2810 2859
          (*_blossom_data)[sb].status = ODD;
2811 2860
          matchedToOdd(sb);
2812 2861
          _tree_set->insert(sb, tree);
2813 2862
          (*_blossom_data)[sb].next = next;
2814 2863
          (*_blossom_data)[sb].pred =
2815 2864
            _graph.oppositeArc((*_blossom_data)[tb].next);
2816 2865

	
2817 2866
          (*_blossom_data)[tb].status = EVEN;
2818 2867
          matchedToEven(tb, tree);
2819 2868
          _tree_set->insert(tb, tree);
2820 2869
          (*_blossom_data)[tb].pred =
2821 2870
            (*_blossom_data)[tb].next =
2822 2871
            _graph.oppositeArc((*_blossom_data)[ub].next);
2823 2872
          next = (*_blossom_data)[ub].next;
2824 2873
        }
2825 2874

	
2826 2875
        (*_blossom_data)[subblossoms[ib]].status = ODD;
2827 2876
        matchedToOdd(subblossoms[ib]);
2828 2877
        _tree_set->insert(subblossoms[ib], tree);
2829 2878
        (*_blossom_data)[subblossoms[ib]].next = next;
2830 2879
        (*_blossom_data)[subblossoms[ib]].pred = pred;
2831 2880
      }
2832 2881
      _tree_set->erase(blossom);
2833 2882
    }
2834 2883

	
2835 2884
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
2836 2885
      if (_blossom_set->trivial(blossom)) {
2837 2886
        int bi = (*_node_index)[base];
2838 2887
        Value pot = (*_node_data)[bi].pot;
2839 2888

	
2840 2889
        (*_matching)[base] = matching;
2841 2890
        _blossom_node_list.push_back(base);
2842 2891
        (*_node_potential)[base] = pot;
2843 2892
      } else {
2844 2893

	
2845 2894
        Value pot = (*_blossom_data)[blossom].pot;
2846 2895
        int bn = _blossom_node_list.size();
2847 2896

	
2848 2897
        std::vector<int> subblossoms;
2849 2898
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
2850 2899
        int b = _blossom_set->find(base);
2851 2900
        int ib = -1;
2852 2901
        for (int i = 0; i < int(subblossoms.size()); ++i) {
2853 2902
          if (subblossoms[i] == b) { ib = i; break; }
2854 2903
        }
2855 2904

	
2856 2905
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
2857 2906
          int sb = subblossoms[(ib + i) % subblossoms.size()];
2858 2907
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
2859 2908

	
2860 2909
          Arc m = (*_blossom_data)[tb].next;
2861 2910
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
2862 2911
          extractBlossom(tb, _graph.source(m), m);
2863 2912
        }
2864 2913
        extractBlossom(subblossoms[ib], base, matching);
2865 2914

	
2866 2915
        int en = _blossom_node_list.size();
2867 2916

	
2868 2917
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
2869 2918
      }
2870 2919
    }
2871 2920

	
2872 2921
    void extractMatching() {
2873 2922
      std::vector<int> blossoms;
2874 2923
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
2875 2924
        blossoms.push_back(c);
2876 2925
      }
2877 2926

	
2878 2927
      for (int i = 0; i < int(blossoms.size()); ++i) {
2879 2928

	
2880 2929
        Value offset = (*_blossom_data)[blossoms[i]].offset;
2881 2930
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
2882 2931
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
2883 2932
             n != INVALID; ++n) {
2884 2933
          (*_node_data)[(*_node_index)[n]].pot -= offset;
2885 2934
        }
2886 2935

	
2887 2936
        Arc matching = (*_blossom_data)[blossoms[i]].next;
2888 2937
        Node base = _graph.source(matching);
2889 2938
        extractBlossom(blossoms[i], base, matching);
2890 2939
      }
2891 2940
    }
2892 2941

	
2893 2942
  public:
2894 2943

	
2895 2944
    /// \brief Constructor
2896 2945
    ///
2897 2946
    /// Constructor.
2898 2947
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
2899 2948
      : _graph(graph), _weight(weight), _matching(0),
2900 2949
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
2901 2950
        _node_num(0), _blossom_num(0),
2902 2951

	
2903 2952
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
2904 2953
        _node_index(0), _node_heap_index(0), _node_data(0),
2905 2954
        _tree_set_index(0), _tree_set(0),
2906 2955

	
2907 2956
        _delta2_index(0), _delta2(0),
2908 2957
        _delta3_index(0), _delta3(0),
2909 2958
        _delta4_index(0), _delta4(0),
2910 2959

	
2911 2960
        _delta_sum() {}
2912 2961

	
2913 2962
    ~MaxWeightedPerfectMatching() {
2914 2963
      destroyStructures();
2915 2964
    }
2916 2965

	
2917 2966
    /// \name Execution Control
2918 2967
    /// The simplest way to execute the algorithm is to use the
2919 2968
    /// \ref run() member function.
2920 2969

	
2921 2970
    ///@{
2922 2971

	
2923 2972
    /// \brief Initialize the algorithm
2924 2973
    ///
2925 2974
    /// This function initializes the algorithm.
2926 2975
    void init() {
2927 2976
      createStructures();
2928 2977

	
2978
      _blossom_node_list.clear();
2979
      _blossom_potential.clear();
2980

	
2929 2981
      for (ArcIt e(_graph); e != INVALID; ++e) {
2930 2982
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
2931 2983
      }
2932 2984
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2933 2985
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
2934 2986
      }
2935 2987
      for (int i = 0; i < _blossom_num; ++i) {
2936 2988
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
2937 2989
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
2938 2990
      }
2939 2991

	
2992
      _delta2->clear();
2993
      _delta3->clear();
2994
      _delta4->clear();
2995
      _blossom_set->clear();
2996
      _tree_set->clear();
2997

	
2940 2998
      int index = 0;
2941 2999
      for (NodeIt n(_graph); n != INVALID; ++n) {
2942 3000
        Value max = - std::numeric_limits<Value>::max();
2943 3001
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
2944 3002
          if (_graph.target(e) == n) continue;
2945 3003
          if ((dualScale * _weight[e]) / 2 > max) {
2946 3004
            max = (dualScale * _weight[e]) / 2;
2947 3005
          }
2948 3006
        }
2949 3007
        (*_node_index)[n] = index;
3008
        (*_node_data)[index].heap_index.clear();
3009
        (*_node_data)[index].heap.clear();
2950 3010
        (*_node_data)[index].pot = max;
2951 3011
        int blossom =
2952 3012
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
2953 3013

	
2954 3014
        _tree_set->insert(blossom);
2955 3015

	
2956 3016
        (*_blossom_data)[blossom].status = EVEN;
2957 3017
        (*_blossom_data)[blossom].pred = INVALID;
2958 3018
        (*_blossom_data)[blossom].next = INVALID;
2959 3019
        (*_blossom_data)[blossom].pot = 0;
2960 3020
        (*_blossom_data)[blossom].offset = 0;
2961 3021
        ++index;
2962 3022
      }
2963 3023
      for (EdgeIt e(_graph); e != INVALID; ++e) {
2964 3024
        int si = (*_node_index)[_graph.u(e)];
2965 3025
        int ti = (*_node_index)[_graph.v(e)];
2966 3026
        if (_graph.u(e) != _graph.v(e)) {
2967 3027
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
2968 3028
                            dualScale * _weight[e]) / 2);
2969 3029
        }
2970 3030
      }
2971 3031
    }
2972 3032

	
2973 3033
    /// \brief Start the algorithm
2974 3034
    ///
2975 3035
    /// This function starts the algorithm.
2976 3036
    ///
2977 3037
    /// \pre \ref init() must be called before using this function.
2978 3038
    bool start() {
2979 3039
      enum OpType {
2980 3040
        D2, D3, D4
2981 3041
      };
2982 3042

	
2983 3043
      int unmatched = _node_num;
2984 3044
      while (unmatched > 0) {
2985 3045
        Value d2 = !_delta2->empty() ?
2986 3046
          _delta2->prio() : std::numeric_limits<Value>::max();
2987 3047

	
2988 3048
        Value d3 = !_delta3->empty() ?
2989 3049
          _delta3->prio() : std::numeric_limits<Value>::max();
2990 3050

	
2991 3051
        Value d4 = !_delta4->empty() ?
2992 3052
          _delta4->prio() : std::numeric_limits<Value>::max();
2993 3053

	
2994 3054
        _delta_sum = d2; OpType ot = D2;
2995 3055
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
2996 3056
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
2997 3057

	
2998 3058
        if (_delta_sum == std::numeric_limits<Value>::max()) {
2999 3059
          return false;
3000 3060
        }
3001 3061

	
3002 3062
        switch (ot) {
3003 3063
        case D2:
3004 3064
          {
3005 3065
            int blossom = _delta2->top();
3006 3066
            Node n = _blossom_set->classTop(blossom);
3007 3067
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
3008 3068
            extendOnArc(e);
3009 3069
          }
3010 3070
          break;
3011 3071
        case D3:
3012 3072
          {
3013 3073
            Edge e = _delta3->top();
3014 3074

	
3015 3075
            int left_blossom = _blossom_set->find(_graph.u(e));
3016 3076
            int right_blossom = _blossom_set->find(_graph.v(e));
3017 3077

	
3018 3078
            if (left_blossom == right_blossom) {
3019 3079
              _delta3->pop();
3020 3080
            } else {
3021 3081
              int left_tree = _tree_set->find(left_blossom);
3022 3082
              int right_tree = _tree_set->find(right_blossom);
3023 3083

	
3024 3084
              if (left_tree == right_tree) {
3025 3085
                shrinkOnEdge(e, left_tree);
3026 3086
              } else {
3027 3087
                augmentOnEdge(e);
3028 3088
                unmatched -= 2;
3029 3089
              }
3030 3090
            }
3031 3091
          } break;
3032 3092
        case D4:
3033 3093
          splitBlossom(_delta4->top());
3034 3094
          break;
3035 3095
        }
3036 3096
      }
3037 3097
      extractMatching();
3038 3098
      return true;
3039 3099
    }
3040 3100

	
3041 3101
    /// \brief Run the algorithm.
3042 3102
    ///
3043 3103
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
3044 3104
    ///
3045 3105
    /// \note mwpm.run() is just a shortcut of the following code.
3046 3106
    /// \code
3047 3107
    ///   mwpm.init();
3048 3108
    ///   mwpm.start();
3049 3109
    /// \endcode
3050 3110
    bool run() {
3051 3111
      init();
3052 3112
      return start();
3053 3113
    }
3054 3114

	
3055 3115
    /// @}
3056 3116

	
3057 3117
    /// \name Primal Solution
3058 3118
    /// Functions to get the primal solution, i.e. the maximum weighted 
3059 3119
    /// perfect matching.\n
3060 3120
    /// Either \ref run() or \ref start() function should be called before
3061 3121
    /// using them.
3062 3122

	
3063 3123
    /// @{
3064 3124

	
3065 3125
    /// \brief Return the weight of the matching.
3066 3126
    ///
3067 3127
    /// This function returns the weight of the found matching.
3068 3128
    ///
3069 3129
    /// \pre Either run() or start() must be called before using this function.
3070 3130
    Value matchingWeight() const {
3071 3131
      Value sum = 0;
3072 3132
      for (NodeIt n(_graph); n != INVALID; ++n) {
3073 3133
        if ((*_matching)[n] != INVALID) {
3074 3134
          sum += _weight[(*_matching)[n]];
3075 3135
        }
3076 3136
      }
3077 3137
      return sum /= 2;
3078 3138
    }
3079 3139

	
3080 3140
    /// \brief Return \c true if the given edge is in the matching.
3081 3141
    ///
3082 3142
    /// This function returns \c true if the given edge is in the found 
3083 3143
    /// matching.
3084 3144
    ///
3085 3145
    /// \pre Either run() or start() must be called before using this function.
3086 3146
    bool matching(const Edge& edge) const {
3087 3147
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
3088 3148
    }
3089 3149

	
3090 3150
    /// \brief Return the matching arc (or edge) incident to the given node.
3091 3151
    ///
3092 3152
    /// This function returns the matching arc (or edge) incident to the
3093 3153
    /// given node in the found matching or \c INVALID if the node is 
3094 3154
    /// not covered by the matching.
3095 3155
    ///
3096 3156
    /// \pre Either run() or start() must be called before using this function.
3097 3157
    Arc matching(const Node& node) const {
3098 3158
      return (*_matching)[node];
3099 3159
    }
3100 3160

	
3101 3161
    /// \brief Return a const reference to the matching map.
3102 3162
    ///
3103 3163
    /// This function returns a const reference to a node map that stores
3104 3164
    /// the matching arc (or edge) incident to each node.
3105 3165
    const MatchingMap& matchingMap() const {
3106 3166
      return *_matching;
3107 3167
    }
3108 3168

	
3109 3169
    /// \brief Return the mate of the given node.
3110 3170
    ///
3111 3171
    /// This function returns the mate of the given node in the found 
3112 3172
    /// matching or \c INVALID if the node is not covered by the matching.
3113 3173
    ///
3114 3174
    /// \pre Either run() or start() must be called before using this function.
3115 3175
    Node mate(const Node& node) const {
3116 3176
      return _graph.target((*_matching)[node]);
3117 3177
    }
3118 3178

	
3119 3179
    /// @}
3120 3180

	
3121 3181
    /// \name Dual Solution
3122 3182
    /// Functions to get the dual solution.\n
3123 3183
    /// Either \ref run() or \ref start() function should be called before
3124 3184
    /// using them.
3125 3185

	
3126 3186
    /// @{
3127 3187

	
3128 3188
    /// \brief Return the value of the dual solution.
3129 3189
    ///
3130 3190
    /// This function returns the value of the dual solution. 
3131 3191
    /// It should be equal to the primal value scaled by \ref dualScale 
3132 3192
    /// "dual scale".
3133 3193
    ///
3134 3194
    /// \pre Either run() or start() must be called before using this function.
3135 3195
    Value dualValue() const {
3136 3196
      Value sum = 0;
3137 3197
      for (NodeIt n(_graph); n != INVALID; ++n) {
3138 3198
        sum += nodeValue(n);
3139 3199
      }
3140 3200
      for (int i = 0; i < blossomNum(); ++i) {
3141 3201
        sum += blossomValue(i) * (blossomSize(i) / 2);
3142 3202
      }
3143 3203
      return sum;
3144 3204
    }
3145 3205

	
3146 3206
    /// \brief Return the dual value (potential) of the given node.
3147 3207
    ///
3148 3208
    /// This function returns the dual value (potential) of the given node.
3149 3209
    ///
3150 3210
    /// \pre Either run() or start() must be called before using this function.
3151 3211
    Value nodeValue(const Node& n) const {
3152 3212
      return (*_node_potential)[n];
3153 3213
    }
3154 3214

	
3155 3215
    /// \brief Return the number of the blossoms in the basis.
3156 3216
    ///
3157 3217
    /// This function returns the number of the blossoms in the basis.
3158 3218
    ///
3159 3219
    /// \pre Either run() or start() must be called before using this function.
3160 3220
    /// \see BlossomIt
3161 3221
    int blossomNum() const {
3162 3222
      return _blossom_potential.size();
3163 3223
    }
3164 3224

	
3165 3225
    /// \brief Return the number of the nodes in the given blossom.
3166 3226
    ///
3167 3227
    /// This function returns the number of the nodes in the given blossom.
3168 3228
    ///
3169 3229
    /// \pre Either run() or start() must be called before using this function.
3170 3230
    /// \see BlossomIt
3171 3231
    int blossomSize(int k) const {
3172 3232
      return _blossom_potential[k].end - _blossom_potential[k].begin;
3173 3233
    }
3174 3234

	
3175 3235
    /// \brief Return the dual value (ptential) of the given blossom.
3176 3236
    ///
3177 3237
    /// This function returns the dual value (ptential) of the given blossom.
3178 3238
    ///
3179 3239
    /// \pre Either run() or start() must be called before using this function.
3180 3240
    Value blossomValue(int k) const {
3181 3241
      return _blossom_potential[k].value;
3182 3242
    }
3183 3243

	
3184 3244
    /// \brief Iterator for obtaining the nodes of a blossom.
3185 3245
    ///
3186 3246
    /// This class provides an iterator for obtaining the nodes of the 
3187 3247
    /// given blossom. It lists a subset of the nodes.
3188 3248
    /// Before using this iterator, you must allocate a 
3189 3249
    /// MaxWeightedPerfectMatching class and execute it.
3190 3250
    class BlossomIt {
3191 3251
    public:
3192 3252

	
3193 3253
      /// \brief Constructor.
3194 3254
      ///
3195 3255
      /// Constructor to get the nodes of the given variable.
3196 3256
      ///
3197 3257
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
3198 3258
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
3199 3259
      /// must be called before initializing this iterator.
3200 3260
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
3201 3261
        : _algorithm(&algorithm)
3202 3262
      {
3203 3263
        _index = _algorithm->_blossom_potential[variable].begin;
3204 3264
        _last = _algorithm->_blossom_potential[variable].end;
3205 3265
      }
3206 3266

	
3207 3267
      /// \brief Conversion to \c Node.
3208 3268
      ///
3209 3269
      /// Conversion to \c Node.
3210 3270
      operator Node() const {
3211 3271
        return _algorithm->_blossom_node_list[_index];
3212 3272
      }
3213 3273

	
3214 3274
      /// \brief Increment operator.
3215 3275
      ///
3216 3276
      /// Increment operator.
3217 3277
      BlossomIt& operator++() {
3218 3278
        ++_index;
3219 3279
        return *this;
3220 3280
      }
3221 3281

	
3222 3282
      /// \brief Validity checking
3223 3283
      ///
3224 3284
      /// This function checks whether the iterator is invalid.
3225 3285
      bool operator==(Invalid) const { return _index == _last; }
3226 3286

	
3227 3287
      /// \brief Validity checking
3228 3288
      ///
3229 3289
      /// This function checks whether the iterator is valid.
3230 3290
      bool operator!=(Invalid) const { return _index != _last; }
3231 3291

	
3232 3292
    private:
3233 3293
      const MaxWeightedPerfectMatching* _algorithm;
3234 3294
      int _last;
3235 3295
      int _index;
3236 3296
    };
3237 3297

	
3238 3298
    /// @}
3239 3299

	
3240 3300
  };
3241 3301

	
3242 3302
} //END OF NAMESPACE LEMON
3243 3303

	
3244 3304
#endif //LEMON_MAX_MATCHING_H
Ignore white space 6 line context
... ...
@@ -358,1317 +358,1326 @@
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
    /// \brief Clears the union-find data structure
1292
    ///
1293
    /// Erase each item from the data structure.
1294
    void clear() {
1295
      nodes.clear();
1296
      classes.clear();
1297
      first_free_node = first_free_class = first_class = -1;
1298
    }
1299

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

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

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

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

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

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

	
1319 1328
      if (first_class != -1) {
1320 1329
        classes[first_class].prev = class_id;
1321 1330
      }
1322 1331
      classes[class_id].next = first_class;
1323 1332
      classes[class_id].prev = -1;
1324 1333
      first_class = class_id;
1325 1334

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

	
1328 1337
      return class_id;
1329 1338
    }
1330 1339

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

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

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

	
1359 1368
        if (first_class != -1) {
1360 1369
          classes[first_class].prev = class_id;
1361 1370
        }
1362 1371
        classes[class_id].next = first_class;
1363 1372
        classes[class_id].prev = -1;
1364 1373
        first_class = class_id;
1365 1374

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

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

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

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

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

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

	
1386 1395
      }
1387 1396

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

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

	
1409 1418
              if (less(~classes[r].parent, right_id)) {
1410 1419
                nodes[new_id].item = nodes[~classes[r].parent].item;
1411 1420
                nodes[new_id].prio = nodes[~classes[r].parent].prio;
1412 1421
              } else {
1413 1422
                nodes[new_id].item = nodes[right_id].item;
1414 1423
                nodes[new_id].prio = nodes[right_id].prio;
1415 1424
              }
1416 1425

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

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

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

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

	
1456 1465
              if (less(~classes[l].parent, left_id)) {
1457 1466
                nodes[new_id].item = nodes[~classes[l].parent].item;
1458 1467
                nodes[new_id].prio = nodes[~classes[l].parent].prio;
1459 1468
              } else {
1460 1469
                nodes[new_id].item = nodes[left_id].item;
1461 1470
                nodes[new_id].prio = nodes[left_id].prio;
1462 1471
              }
1463 1472

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

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

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

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

	
1510 1519
              classes[l].parent = ~new_parent;
1511 1520
              classes[l].depth += 1;
1512 1521
              nodes[new_parent].parent = ~l;
1513 1522
            }
1514 1523
          }
1515 1524
          if (classes[r].next != -1) {
1516 1525
            classes[classes[r].next].prev = classes[r].prev;
1517 1526
          }
1518 1527
          classes[classes[r].prev].next = classes[r].next;
1519 1528

	
1520 1529
          classes[r].prev = classes[l].right;
1521 1530
          classes[classes[l].right].next = r;
1522 1531
          classes[l].right = r;
1523 1532
          classes[r].parent = l;
1524 1533

	
1525 1534
          classes[r].next = -1;
1526 1535
          classes[r].depth = rln;
1527 1536
        }
1528 1537
      }
1529 1538
      return class_id;
1530 1539
    }
1531 1540

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

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

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

	
1554 1563
        *out++ = l;
1555 1564

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

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

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

	
1570 1579
        deleteClass(id);
1571 1580
      }
1572 1581

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

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

	
1587 1596
            split(r, new_node);
1588 1597
            pushAfter(l, new_node);
1589 1598
            setPrio(l);
1590 1599
            setPrio(new_node);
1591 1600
            r = new_node;
1592 1601
          }
1593 1602
          classes[cs[i]].parent = ~r;
1594 1603
          classes[cs[i]].depth = classes[~(nodes[l].parent)].depth;
1595 1604
          nodes[r].parent = ~cs[i];
1596 1605

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

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

	
1603 1612
          *out++ = cs[i];
1604 1613
        }
1605 1614
      }
1606 1615
    }
1607 1616

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

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

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

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

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

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

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