src/work/johanna/unionfind.h
changeset 202 0bd4fe53b1d0
child 218 5964f1c64ca1
equal deleted inserted replaced
-1:000000000000 0:1285910d7327
       
     1 // -*- c++ -*- //
       
     2 #ifndef UNION_FIND_H
       
     3 #define UNION_FIND_H
       
     4 
       
     5 #include <vector>
       
     6 #include <utility>
       
     7 
       
     8 namespace hugo {
       
     9 
       
    10   template <typename T, typename TIntMap>
       
    11   class UnionFind {
       
    12     
       
    13   public:
       
    14     typedef T ElementType;
       
    15     typedef std::pair<int,int> PairType;
       
    16 
       
    17   private:
       
    18     std::vector<PairType> data;
       
    19     TIntMap& map;
       
    20 
       
    21   public:
       
    22     UnionFind(TIntMap& m) : map(m) {}
       
    23 
       
    24 
       
    25     int whichComponent(T a)
       
    26     {
       
    27       int comp0 = map.get(a);
       
    28       if (comp0 < 0) {
       
    29 	return insertNewElement(a);
       
    30       }
       
    31       int comp = comp0;
       
    32       int next;
       
    33       while ( (next = data[comp].first) != comp) {
       
    34 	comp = next;
       
    35       }
       
    36       while ( (next = data[comp0].first) != comp) {
       
    37 	data[comp0].first = comp;
       
    38 	comp0 = next;
       
    39       }
       
    40 
       
    41       return comp;
       
    42     }
       
    43 
       
    44     int insertNewElement(T a)
       
    45     {
       
    46       int n = data.size();
       
    47       data.push_back(make_pair(n, 1));
       
    48       map.set(a,n);
       
    49       return n;
       
    50     }
       
    51 
       
    52     bool joinComponents(T a, T b)
       
    53     {
       
    54       int ca = whichComponent(a);
       
    55       int cb = whichComponent(b);
       
    56 
       
    57       if ( ca == cb ) 
       
    58 	return false;
       
    59 
       
    60       if ( data[ca].second > data[cb].second ) {
       
    61 	data[cb].first = ca;
       
    62 	data[ca].second += data[cb].second;
       
    63       }
       
    64       else {
       
    65 	data[ca].first = cb;
       
    66 	data[cb].second += data[ca].second;
       
    67       }
       
    68       return true;
       
    69     }
       
    70 
       
    71   };
       
    72 
       
    73 } //namespace hugo
       
    74 
       
    75 #endif //UNION_FIND_H