| [250] | 1 | // -*- C++ -*- // | 
|---|
 | 2 | /* | 
|---|
 | 3 | Union-Find structure | 
|---|
 | 4 |  | 
|---|
 | 5 | * Ehhez nagyon fontos, hogy az atadott property map inicializalva legyen | 
|---|
 | 6 | * minden szobajovo kulcs ertekre, -1 -es ertekkel! | 
|---|
 | 7 |   | 
|---|
 | 8 | */ | 
|---|
 | 9 | #ifndef UNION_FIND_H | 
|---|
 | 10 | #define UNION_FIND_H | 
|---|
 | 11 |  | 
|---|
 | 12 | #include <vector> | 
|---|
 | 13 | //#include <map> | 
|---|
 | 14 |  | 
|---|
 | 15 |  | 
|---|
 | 16 | namespace hugo { | 
|---|
 | 17 |    | 
|---|
 | 18 |   template <typename KeyType, typename KeyIntMap> | 
|---|
 | 19 |     class UnionFind { | 
|---|
 | 20 |     KeyIntMap& pointmap; | 
|---|
 | 21 |     struct VectorElementType { | 
|---|
 | 22 |       int boss; | 
|---|
 | 23 |       int count; | 
|---|
 | 24 |       VectorElementType(int _boss, int _count){ | 
|---|
 | 25 |         boss = _boss; | 
|---|
 | 26 |         count = _count; | 
|---|
 | 27 |       } | 
|---|
 | 28 |     }; | 
|---|
 | 29 |     std::vector<VectorElementType> container; | 
|---|
 | 30 |     public: | 
|---|
 | 31 |        | 
|---|
 | 32 |     UnionFind(KeyIntMap& _pointmap): pointmap(_pointmap){ | 
|---|
 | 33 |        | 
|---|
 | 34 |     }  | 
|---|
 | 35 |      | 
|---|
 | 36 |     //Give a component of one point to the structure | 
|---|
 | 37 |     int addPoint(KeyType u){ | 
|---|
 | 38 |       int _index = container.size(); | 
|---|
 | 39 |       VectorElementType buf(_index,1); | 
|---|
 | 40 |       container.push_back(buf); | 
|---|
 | 41 |       return _index; | 
|---|
 | 42 |     } | 
|---|
 | 43 |  | 
|---|
 | 44 |      | 
|---|
 | 45 |     //Finds the big boss of u | 
|---|
 | 46 |     int find(KeyType u){ | 
|---|
 | 47 |       if (pointmap.get(u)==-1){ | 
|---|
 | 48 |         int whoami = addPoint(u); | 
|---|
 | 49 |         pointmap.set(u, whoami); | 
|---|
 | 50 |         return whoami; | 
|---|
 | 51 |       } | 
|---|
 | 52 |       else{ | 
|---|
 | 53 |         int emp = pointmap.get(u); | 
|---|
 | 54 |         int boss = container[emp].boss; | 
|---|
 | 55 |         while(emp != boss){ | 
|---|
 | 56 |           emp = boss; | 
|---|
 | 57 |           boss = container[emp].boss; | 
|---|
 | 58 |         } | 
|---|
 | 59 |         return boss; | 
|---|
 | 60 |       } | 
|---|
 | 61 |     } | 
|---|
 | 62 |  | 
|---|
 | 63 |     //Finds u and v in the structures and merges the comopnents, if not equal | 
|---|
 | 64 |     bool findAndMerge(KeyType u,KeyType v){ | 
|---|
 | 65 |       int bu = find(u); | 
|---|
 | 66 |       int bv = find(v); | 
|---|
 | 67 |       if (bu != bv){ | 
|---|
 | 68 |         unio(bu,bv); | 
|---|
 | 69 |         return true; | 
|---|
 | 70 |       } | 
|---|
 | 71 |       else{ | 
|---|
 | 72 |         return false; | 
|---|
 | 73 |       } | 
|---|
 | 74 |     } | 
|---|
 | 75 |  | 
|---|
 | 76 |     //Merges a into b | 
|---|
 | 77 |     void mergeInto(int a, int b){ | 
|---|
 | 78 |       container[a].boss = b; | 
|---|
 | 79 |       container[b].count +=  container[a].count; | 
|---|
 | 80 |     } | 
|---|
 | 81 |      | 
|---|
 | 82 |     //Makes the union | 
|---|
 | 83 |     void unio(int b1, int b2){ | 
|---|
 | 84 |       if (container[b1].count>container[b2].count){ | 
|---|
 | 85 |         mergeInto(b2,b1); | 
|---|
 | 86 |       } | 
|---|
 | 87 |       else{ | 
|---|
 | 88 |         mergeInto(b1,b2); | 
|---|
 | 89 |       } | 
|---|
 | 90 |     }//unio | 
|---|
 | 91 |   }; | 
|---|
 | 92 |    | 
|---|
 | 93 | }//namespace hugo | 
|---|
 | 94 | #endif | 
|---|