disjoint_sets.hpp 2.5 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. namespace boost
  8. {
  9. namespace detail
  10. {
  11. template < class ParentPA, class Vertex >
  12. Vertex find_representative_with_path_halving(ParentPA p, Vertex v)
  13. {
  14. Vertex parent = get(p, v);
  15. Vertex grandparent = get(p, parent);
  16. while (parent != grandparent)
  17. {
  18. put(p, v, grandparent);
  19. v = grandparent;
  20. parent = get(p, v);
  21. grandparent = get(p, parent);
  22. }
  23. return parent;
  24. }
  25. template < class ParentPA, class Vertex >
  26. Vertex find_representative_with_full_compression(ParentPA parent, Vertex v)
  27. {
  28. Vertex old = v;
  29. Vertex ancestor = get(parent, v);
  30. while (ancestor != v)
  31. {
  32. v = ancestor;
  33. ancestor = get(parent, v);
  34. }
  35. v = get(parent, old);
  36. while (ancestor != v)
  37. {
  38. put(parent, old, ancestor);
  39. old = v;
  40. v = get(parent, old);
  41. }
  42. return ancestor;
  43. }
  44. /* the postcondition of link sets is:
  45. component_representative(i) == component_representative(j)
  46. */
  47. template < class ParentPA, class RankPA, class Vertex,
  48. class ComponentRepresentative >
  49. inline void link_sets(ParentPA p, RankPA rank, Vertex i, Vertex j,
  50. ComponentRepresentative comp_rep)
  51. {
  52. i = comp_rep(p, i);
  53. j = comp_rep(p, j);
  54. if (i == j)
  55. return;
  56. if (get(rank, i) > get(rank, j))
  57. put(p, j, i);
  58. else
  59. {
  60. put(p, i, j);
  61. if (get(rank, i) == get(rank, j))
  62. put(rank, j, get(rank, j) + 1);
  63. }
  64. }
  65. // normalize components has the following postcondidition:
  66. // i >= p[i]
  67. // that is, the representative is the node with the smallest index in its
  68. // class as its precondition it it assumes that the node container is
  69. // compressed
  70. template < class ParentPA, class Vertex >
  71. inline void normalize_node(ParentPA p, Vertex i)
  72. {
  73. if (i > get(p, i) || get(p, get(p, i)) != get(p, i))
  74. put(p, i, get(p, get(p, i)));
  75. else
  76. {
  77. put(p, get(p, i), i);
  78. put(p, i, i);
  79. }
  80. }
  81. } // namespace detail
  82. } // namespace boost
  83. #endif // BOOST_DETAIL_DISJOINT_SETS_HPP