disjoint_sets.hpp 2.1 KB

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