Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

UnionFind.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file UnionFind.hpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef UNIONFIND_HPP
00007 #define UNIONFIND_HPP
00008 
00009 #include <cassert>
00010 #include <vector>
00011 #include "Benzene.hpp"
00012 
00013 _BEGIN_BENZENE_NAMESPACE_
00014 
00015 //----------------------------------------------------------------------------
00016 
00017 /** General union/find implementation. */
00018 template<int S>
00019 class UnionFind
00020 {
00021 public:
00022 
00023     /** Constructor.  All elements are initially isolated. */
00024     UnionFind();
00025 
00026     /** Sets all elements to be isolated. */
00027     void Clear();
00028 
00029     /** Returns true if x is the captain of a group. */
00030     bool IsRoot(int x) const;
00031 
00032     /** Gets the captain of x's group. */
00033     int GetRoot(int x) const;
00034 
00035     /** Unions two sets of elements. */
00036     int UnionGroups(int x, int y);
00037 
00038 private:
00039     /** Flag denoting that the element is its own group. */
00040     static const int ISOLATED = -1;
00041 
00042     mutable std::vector<int> m_sets;
00043 };
00044 
00045 template<int S>
00046 inline UnionFind<S>::UnionFind()
00047     : m_sets(S)
00048 {
00049     Clear();
00050 }
00051 
00052 template<int S>
00053 inline void UnionFind<S>::Clear()
00054 {
00055     for (int i = 0; i < S; i++) 
00056         m_sets[i] = ISOLATED;
00057 }
00058 
00059 template<int S> 
00060 inline bool UnionFind<S>::IsRoot(int x) const
00061 {
00062     return m_sets[x] < 0;
00063 }
00064 
00065 template<int S>
00066 inline int UnionFind<S>::GetRoot(int x) const
00067 {
00068     assert(0 <= x && x < S);
00069     if (m_sets[x] < 0) 
00070         return x;
00071     return (m_sets[x] = GetRoot(m_sets[x]));
00072 }
00073 
00074 template<int S>
00075 inline int UnionFind<S>::UnionGroups(int a, int b) 
00076 {
00077     int ra = GetRoot(a);
00078     int rb = GetRoot(b);
00079     if (ra == rb) 
00080         return ra;
00081     // Force the smaller guy to become captain
00082     int cap = std::min(ra, rb);
00083     int non = std::max(ra, rb);
00084     m_sets[cap] += m_sets[non];
00085     m_sets[non] = cap; 
00086     return cap;
00087 }
00088 
00089 //----------------------------------------------------------------------------
00090 
00091 _END_BENZENE_NAMESPACE_
00092 
00093 #endif // UNIONFIND_HPP


6 Jan 2011 Doxygen 1.6.3