Advertisement
kartikkukreja

Articulation Points / Cut Vertices with DFS

Nov 8th, 2013
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.31 KB | None | 0 0
  1. #include <cstdio>
  2. #include <vector>
  3. #include <list>
  4. #include <cstring>
  5. using namespace std;
  6.  
  7. // Class to represent an undirected graph, with vertices labeled
  8. // from 0 to V-1, where V is the number of vertices
  9. class Graph {
  10. private:
  11.     // V is the number of vertices in the graph
  12.     // time is used to determine when a node has a back-link to one of its ancestors
  13.     int V, time;
  14.    
  15.     // adjList[u] is the adjacency list of vertex u, 0 <= u < V
  16.     vector <int> *adjList;
  17.    
  18.     // explored[u] is true if u has been explored
  19.     // articulation_point[u] is true is u is an articulation point
  20.     bool *explored, *articulation_point, done;
  21.    
  22.     // disc_time[u] is the time at which vertex u was explored
  23.     // parent[u] = v if in the dfs tree, there is an edge from v to u
  24.     // low[u] is the time of the earliest explored vertex reachable from u
  25.     // If low[u] < disc_time[u], then there is a back-link from some node in the
  26.     // subtree rooted at u to some ancestor of u
  27.     int *disc_time, *parent, *low;
  28.    
  29.         // articulation_points stores the articulation points/cut vertices in the graph
  30.     vector <int> articulation_points;
  31.  
  32.     void dfsUtil(int u) {
  33.         explored[u] = true;
  34.         int num_child = 0;
  35.         disc_time[u] = low[u] = ++time;
  36.        
  37.         for (vector <int>::iterator v = adjList[u].begin(); v != adjList[u].end(); v++) {
  38.             if (!explored[*v])  {
  39.                 num_child++;
  40.                 parent[*v] = u;
  41.                 dfsUtil(*v);
  42.                 low[u] = min(low[u], low[*v]);
  43.                
  44.         // u is an articulation point iff
  45.         // 1. It the the root and has more than 1 child.
  46.         // 2. It is not the root and no vertex in the subtree rooted at one of its
  47.         //    children has a back-link to its ancestor.
  48.         //    A child has a back-link to an ancestor of its parent when its low
  49.         //    value is less than the discovery time of its parent.
  50.                 if (parent[u] == -1 && num_child > 1)
  51.                     articulation_point[u] = true;
  52.                 else if (parent[u] != -1 && low[*v] >= disc_time[u])
  53.                     articulation_point[u] = true;
  54.             } else if (*v != parent[u])
  55.                 low[u] = min(low[u], disc_time[*v]);
  56.         }
  57.     }
  58.  
  59.     void dfs()    {
  60.         for (int u = 0; u < V; u++)
  61.             if (!explored[u])
  62.                 dfsUtil(u);
  63.     }
  64.  
  65. public:
  66.  
  67.     // create an empty undirected graph having V vertices
  68.     Graph(int V) {
  69.         this->V = V;
  70.         time = 0;
  71.         done = false;
  72.        
  73.         adjList = new vector <int>[V];
  74.         explored = new bool[V];
  75.         articulation_point = new bool[V];
  76.         disc_time = new int[V];
  77.         parent = new int[V];
  78.         low = new int[V];
  79.        
  80.         memset(explored, false, V * sizeof(bool));
  81.         memset(articulation_point, false, V * sizeof(bool));
  82.         memset(parent, -1, V * sizeof (int));
  83.     }
  84.  
  85.     ~Graph()    {
  86.         delete [] adjList;
  87.         delete [] articulation_point;
  88.         delete [] explored;
  89.         delete [] parent;
  90.         delete [] disc_time;
  91.         delete [] low;
  92.     }
  93.  
  94.     // add an undirected edge (u, v) to the graph
  95.     // returns false if either u or v is less than 0 or greater than equal to V
  96.     // returns true if the edge was added to the digraph
  97.     bool addEdge(int u, int v)  {
  98.         if (u < 0 || u >= V) return false;
  99.         if (v < 0 || v >= V) return false;
  100.         adjList[u].push_back(v);
  101.         adjList[v].push_back(u);
  102.         return true;
  103.     }
  104.    
  105.     // Performs dfs over the graph and returns a vector containing
  106.     // the articulation points
  107.     vector <int> getArticulationPoints()    {
  108.         if (done)
  109.             return articulation_points;
  110.         dfs();
  111.         done = true;
  112.         for (int u = 0; u < V; u++)
  113.             if (articulation_point[u])
  114.                 articulation_points.push_back(u);
  115.         return articulation_points;
  116.     }
  117. };
  118.  
  119. int main() {
  120.     Graph G(5);
  121.  
  122.     G.addEdge(1, 0);
  123.     G.addEdge(1, 2);
  124.     G.addEdge(2, 0);
  125.     G.addEdge(0, 3);
  126.     G.addEdge(3, 4);
  127.  
  128.     vector <int> articulationPoints = G.getArticulationPoints();
  129.     printf("Graph has %d articulation points given below :\n", articulationPoints.size());
  130.     for (vector <int> :: iterator u = articulationPoints.begin(); u != articulationPoints.end(); u++)
  131.         printf("%d ", *u);
  132.     printf("\n");
  133.  
  134.     return 0;
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement