cmComputeComponentGraph.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 "cmStandardIncludes.h"
  13. #include "cmGraphAdjacencyList.h"
  14. #include <stack>
  15. /** \class cmComputeComponentGraph
  16. * \brief Analyze a graph to determine strongly connected components.
  17. *
  18. * Convert a directed graph into a directed acyclic graph whose nodes
  19. * correspond to strongly connected components of the original graph.
  20. *
  21. * We use Tarjan's algorithm to enumerate the components efficiently.
  22. * An advantage of this approach is that the components are identified
  23. * in a topologically sorted order.
  24. */
  25. class cmComputeComponentGraph
  26. {
  27. public:
  28. // Represent the graph with an adjacency list.
  29. typedef cmGraphNodeList NodeList;
  30. typedef cmGraphEdgeList EdgeList;
  31. typedef cmGraphAdjacencyList Graph;
  32. cmComputeComponentGraph(Graph const& input);
  33. ~cmComputeComponentGraph();
  34. /** Get the adjacency list of the component graph. */
  35. Graph const& GetComponentGraph() const
  36. { return this->ComponentGraph; }
  37. EdgeList const& GetComponentGraphEdges(int c) const
  38. { return this->ComponentGraph[c]; }
  39. /** Get map from component index to original node indices. */
  40. std::vector<NodeList> const& GetComponents() const
  41. { return this->Components; }
  42. NodeList const& GetComponent(int c) const
  43. { return this->Components[c]; }
  44. /** Get map from original node index to component index. */
  45. std::vector<int> const& GetComponentMap() const
  46. { return this->TarjanComponents; }
  47. private:
  48. void TransferEdges();
  49. Graph const& InputGraph;
  50. Graph ComponentGraph;
  51. // Tarjan's algorithm.
  52. struct TarjanEntry
  53. {
  54. int Root;
  55. int VisitIndex;
  56. };
  57. std::vector<int> TarjanVisited;
  58. std::vector<int> TarjanComponents;
  59. std::vector<TarjanEntry> TarjanEntries;
  60. std::vector<NodeList> Components;
  61. std::stack<int> TarjanStack;
  62. int TarjanWalkId;
  63. int TarjanIndex;
  64. void Tarjan();
  65. void TarjanVisit(int i);
  66. // Connected components.
  67. };
  68. #endif