src/work/athos/union_find.h
author alpar
Sat, 17 Apr 2004 13:15:53 +0000
changeset 348 b63ea19e502e
child 921 818510fa3d99
permissions -rw-r--r--
A bool Edge Map with iterators that goes through the true or the false edges.
     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