disjoint_sets.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // (C) Copyright Jeremy Siek 2004
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_DETAIL_DISJOINT_SETS_HPP
  6. #define BOOST_DETAIL_DISJOINT_SETS_HPP
  7. #include <cassert>
  8. namespace boost
  9. {
  10. namespace detail
  11. {
  12. template < class ParentPA, class Vertex >
  13. Vertex find_representative_with_path_halving(ParentPA p, Vertex v)
  14. {
  15. Vertex parent = get(p, v);
  16. Vertex grandparent = get(p, parent);
  17. while (parent != grandparent)
  18. {
  19. put(p, v, grandparent);
  20. v = grandparent;
  21. parent = get(p, v);
  22. grandparent = get(p, parent);
  23. }
  24. return parent;
  25. }
  26. template < class ParentPA, class Vertex >
  27. Vertex find_representative_with_full_compression(ParentPA parent, Vertex v)
  28. {
  29. Vertex old = v;
  30. Vertex ancestor = get(parent, v);
  31. while (ancestor != v)
  32. {
  33. v = ancestor;
  34. ancestor = get(parent, v);
  35. }
  36. v = get(parent, old);
  37. while (ancestor != v)
  38. {
  39. put(parent, old, ancestor);
  40. old = v;
  41. v = get(parent, old);
  42. }
  43. return ancestor;
  44. }
  45. /* the postcondition of link sets is:
  46. component_representative(i) == component_representative(j)
  47. */
  48. template < class ParentPA, class RankPA, class Vertex>
  49. inline void link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j)
  50. {
  51. assert(i == get(p, i));
  52. assert(j == get(p, j));
  53. if (i == j)
  54. return;
  55. if (get(rank, i) > get(rank, j))
  56. put(p, j, i);
  57. else
  58. {
  59. put(p, i, j);
  60. if (get(rank, i) == get(rank, j))
  61. put(rank, j, get(rank, j) + 1);
  62. }
  63. }
  64. // normalize components has the following postcondidition:
  65. // i >= p[i]
  66. // that is, the representative is the node with the smallest index in its
  67. // class as its precondition it it assumes that the node container is
  68. // compressed
  69. template < class ParentPA, class Vertex >
  70. inline void normalize_node(ParentPA p, Vertex i)
  71. {
  72. if (i > get(p, i) || get(p, get(p, i)) != get(p, i))
  73. put(p, i, get(p, get(p, i)));
  74. else
  75. {
  76. put(p, get(p, i), i);
  77. put(p, i, i);
  78. }
  79. }
  80. } // namespace detail
  81. } // namespace boost
  82. #endif // BOOST_DETAIL_DISJOINT_SETS_HPP