cmComputeComponentGraph.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #ifndef cmComputeComponentGraph_h
  11. #define cmComputeComponentGraph_h
  12. #include <cmConfigure.h> // IWYU pragma: keep
  13. #include "cmGraphAdjacencyList.h"
  14. #include <stack>
  15. #include <vector>
  16. /** \class cmComputeComponentGraph
  17. * \brief Analyze a graph to determine strongly connected components.
  18. *
  19. * Convert a directed graph into a directed acyclic graph whose nodes
  20. * correspond to strongly connected components of the original graph.
  21. *
  22. * We use Tarjan's algorithm to enumerate the components efficiently.
  23. * An advantage of this approach is that the components are identified
  24. * in a topologically sorted order.
  25. */
  26. class cmComputeComponentGraph
  27. {
  28. public:
  29. // Represent the graph with an adjacency list.
  30. typedef cmGraphNodeList NodeList;
  31. typedef cmGraphEdgeList EdgeList;
  32. typedef cmGraphAdjacencyList Graph;
  33. cmComputeComponentGraph(Graph const& input);
  34. ~cmComputeComponentGraph();
  35. /** Get the adjacency list of the component graph. */
  36. Graph const& GetComponentGraph() const { return this->ComponentGraph; }
  37. EdgeList const& GetComponentGraphEdges(int c) const
  38. {
  39. return this->ComponentGraph[c];
  40. }
  41. /** Get map from component index to original node indices. */
  42. std::vector<NodeList> const& GetComponents() const
  43. {
  44. return this->Components;
  45. }
  46. NodeList const& GetComponent(int c) const { return this->Components[c]; }
  47. /** Get map from original node index to component index. */
  48. std::vector<int> const& GetComponentMap() const
  49. {
  50. return this->TarjanComponents;
  51. }
  52. private:
  53. void TransferEdges();
  54. Graph const& InputGraph;
  55. Graph ComponentGraph;
  56. // Tarjan's algorithm.
  57. struct TarjanEntry
  58. {
  59. int Root;
  60. int VisitIndex;
  61. };
  62. std::vector<int> TarjanVisited;
  63. std::vector<int> TarjanComponents;
  64. std::vector<TarjanEntry> TarjanEntries;
  65. std::vector<NodeList> Components;
  66. std::stack<int> TarjanStack;
  67. int TarjanWalkId;
  68. int TarjanIndex;
  69. void Tarjan();
  70. void TarjanVisit(int i);
  71. // Connected components.
  72. };
  73. #endif