From bcb0c48f8d9e7a7c6e666d46fab90a78cf90d3a0 Mon Sep 17 00:00:00 2001
From: Bruno Freitas Tissei <bft15@inf.ufpr.br>
Date: Mon, 11 Mar 2019 16:31:14 -0300
Subject: [PATCH] Improve Articulations/Bridges comments

Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br>
---
 algorithms/graph/articulations_bridges.cpp | 36 +++++++++++++++++-----
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/algorithms/graph/articulations_bridges.cpp b/algorithms/graph/articulations_bridges.cpp
index e3a6c69..4943220 100644
--- a/algorithms/graph/articulations_bridges.cpp
+++ b/algorithms/graph/articulations_bridges.cpp
@@ -6,9 +6,15 @@
  */
 
 vector<int> graph[MAX];
+int visited[MAX], parent[MAX];
 
-int cont[MAX], parent[MAX];
-int low[MAX], L[MAX];
+// The level of a node x (L[x]) is the "height" of x relative to the root
+// of the DFS
+int L[MAX];
+
+// The low-link value of a node x (low[x]) is defined as the smallest level
+// of another node reachable from x when doing a DFS
+int low[MAX];
 
 // Answer vector with bridges (edges)
 vector<ii> bridges;
@@ -22,24 +28,35 @@ vector<int> articulations;
  */
 void dfs(int x) {
   int child = 0;
-  cont[x] = 1;
+  visited[x] = 1;
 
   for (auto i : graph[x]) {
-    if (!cont[i]) {
+    if (!visited[i]) {
       child++;
       parent[i] = x;
 
+      // Initially low[i] is equal to low[x]
       low[i] = L[i] = L[x] + 1;
       dfs(i);
+
+      // After the DFS, low[i] might have changed, in that case, low[x]
+      // should be updated if a lower value has been found
       low[x] = min(low[x], low[i]);
 
-      if ((parent[x] == -1 && child > 1) || (parent[x] != -1 &&
-           low[i] >= L[x]))
+      // If x is the root and has more than one child, or if it's not the
+      // root and the child i of x has no back edges, then x is an
+      // articulation vertex
+      if ((parent[x] == -1 && child > 1) || 
+          (parent[x] != -1 && low[i] >= L[x]))
         articulations.pb(x);
 
+      // If node i can't reach a node above x (has no back edges), then it 
+      // the egde (x,i) is a bridge
       if (low[i] > L[x])
         bridges.pb(ii(x, i));
 
+    // If i has been visited but it's not x's parent, then i is "above" 
+    // (has smaller level then x), meaning that the edge (x,i) is a "back edge"
     } else if (parent[x] != i)
       low[x] = min(low[x], L[i]);
   }
@@ -49,9 +66,12 @@ void dfs(int x) {
  * Applies tarjan algorithm and format articulations vector.
  * @param x root vertex 
  */
-void tarjan(int x) {
+void tarjan(int n) {
   mset(parent, -1);
-  dfs(x);
+
+  for (int i = 0; i < n; ++i)
+    if (!visited[i])
+      dfs(i);
 
   // Remove duplicates for articulations
   sort(all(articulations));
-- 
GitLab