Skip to main content

Unit - 5

TITLE

Exploring Graphs​

1. Introduction to Graphs​

1.1 Overview and Key Terminology​

A graph is a versatile non-linear data structure used to model pairwise relationships between objects.

  • Node / Vertex: A fundamental unit or discrete entity representing an object (e.g., city, router, computer, person).
  • Edge / Arc / Link: A connection or relationship between two vertices.
  • Adjacent Vertices: Two vertices are adjacent if they are directly connected by an edge.
  • Degree of a Vertex:
    • In an undirected graph: The total number of edges incident to the vertex.
    • In a directed graph:
      • In-degree: Number of incoming edges arriving at the vertex.
      • Out-degree: Number of outgoing edges departing from the vertex.
  • Path: A sequence of alternating vertices and edges connecting a start vertex to an end vertex.
  • Cycle: A path where the starting vertex and ending vertex are identical, with no other vertices repeated.

1.2 Mathematical Definition of Graphs​

A graph GG is formally defined as an ordered pair:

G=⟨N,A⟩G = \langle N, A \rangle

Where:

  • NN is a non-empty set called the set of nodes (points, vertices): N={v1,v2,…,vn}N = \{v_1, v_2, \dots, v_n\}
  • AA is a set of edges (links, arcs): A={e1,e2,…,em}A = \{e_1, e_2, \dots, e_m\}
  • A mapping function exists from the set of edges AA to pairs of elements of NN.

2. Graph Types and Representations​

2.1 Directed Graph (Digraph)​

  • A graph in which every edge is directed (assigned a specific one-way orientation).
  • Each edge is represented by an ordered pair (u,v)(u, v), indicating a one-way path directed from vertex uu to vertex vv.
  • uu is the initial node (source / predecessor), and vv is the terminal node (target / successor).

2.2 Undirected Graph​

  • A graph in which every edge is bidirectional (undirected).
  • Each edge is represented by an unordered pair {u,v}\{u, v\}, meaning traversal is permitted freely in both directions: u→vu \to v and v→uv \to u.

2.3 Graph Storage Representations​

Graphs are typically implemented in memory using one of two standard data structures:

CriterionAdjacency MatrixAdjacency List
Data Structure2D Array of size ∥V∥×∥V∥\|V\| \times \|V\|Array/Vector of Lists of size ∥V∥\|V\|
Space ComplexityΘ(V2)\Theta(V^2)Θ(V+E)\Theta(V + E)
Edge Lookup (u,v)(u, v)O(1)O(1)O(deg(u))O(\text{deg}(u))
Iterate over NeighborsO(V)O(V)O(deg(u))O(\text{deg}(u))
Best Suited ForDense graphs (E≈V2E \approx V^2)Sparse graphs (E≪V2E \ll V^2)

3. Traversing Graphs vs Trees​

3.1 Tree Traversal Techniques​

A tree is a special, hierarchical form of a connected, acyclic undirected graph with a single root. Standard systematic tree traversals include:

3.1.1 Preorder Traversal​

  1. Visit the root.
  2. Traverse the left subtree in preorder.
  3. Traverse the right subtree in preorder.
  • Rule Order: Root -> Left -> Right

3.1.2 Inorder Traversal​

  1. Traverse the left subtree in inorder.
  2. Visit the root.
  3. Traverse the right subtree in inorder.
  • Rule Order: Left -> Root -> Right

3.1.3 Postorder Traversal​

  1. Traverse the left subtree in postorder.
  2. Traverse the right subtree in postorder.
  3. Visit the root.
  • Rule Order: Left -> Right -> Root

3.2 Transition from Tree Traversal to Graph Traversal​

Traversing general graphs requires additional considerations compared to trees:

  1. Cycles and Infinite Loops: Graphs can have cycles; a node can point back to an ancestor. A mark[v] (visited) table or boolean flag is mandatory to prevent infinite loops.
  2. Disconnected Components: A tree is always connected and accessible from its root; a graph may contain multiple isolated subgraphs. The outer loop must iterate through every vertex v∈Nv \in N to ensure complete coverage.
  3. No Inherent Root: Unlike trees, any vertex v∈Nv \in N can serve as an arbitrary starting point for graph traversal.

4. Depth First Search (DFS)​

4.1 Concept and Core Mechanism​

Depth First Search (DFS) explores as deeply as possible along each branch before backtracking.

Core Traversal Rules
  1. Select any node v∈Nv \in N as the starting point and mark it as visited.
  2. Select an unvisited adjacent node of the current node. Make it the new starting point and mark it as visited (recursive step).
  3. If the current node has no unvisited adjacent nodes, backtrack to its parent node and continue searching.
  4. When all nodes adjacent to vv are marked, the search starting at vv finishes.
  5. If unvisited nodes remain in GG, choose any unvisited node and repeat the procedure.

4.2 DFS Algorithm Pseudocode​

💡 The Big Idea in Plain English​

Think of exploring a dark maze with a piece of chalk: You keep walking as deep as you can down one single path, marking every room as "visited" so you don't go in circles. When you hit a dead end with no unvisited doors left, you turn around (backtrack) to the previous room and try the other doors! You repeat this until every room in the entire building has been explored.

👣 3 Easy Steps to Remember​

  1. Visit and Mark: When you arrive at vertex vv, mark it as visited right away.
  2. Dive as Deep as Possible:
    • For every neighbor ww of vv:
    • If ww is not visited yet, immediately make a recursive call dfs(w)!
  3. Backtrack on Dead Ends:
    • Once all neighbors of vv have been explored, the call returns back up to the parent vertex so it can explore its other branches.

🧠 Memory Trick: Go deep →\to hit dead end →\to backtrack! Uses the recursion call stack (LIFO). Time: O(V+E)O(V + E), Space: O(V)O(V).

4.3 Step-by-Step Execution and Trace Example​

Tracing the 8-node graph shown above starting at node 1:

StepActionNode Visited / Calling StateBacktrack / Neighbor Note
1dfs(1)1Initial call; selects adjacent node 2
2dfs(2)2Recursive call; selects adjacent node 3
3dfs(3)3Recursive call; selects adjacent node 6
4dfs(6)6Recursive call; selects unvisited neighbor 5 (via 2)
5dfs(5)5Recursive call; progress is blocked (no unvisited neighbors)
--BacktrackReturns up to node 1Nodes 2, 3, 5, 6 are already marked visited
6dfs(4)4Node 4 is an unvisited neighbor of node 1
7dfs(7)7Recursive call; selects adjacent node 8
8dfs(8)8Recursive call; all neighbors (4, 7) already visited
9TerminateDoneThere are no more unvisited nodes left in the graph
  • Final Visited Sequence: 1 -> 2 -> 3 -> 6 -> 5 -> 4 -> 7 -> 8

4.4 Complexity and Properties​

  • Time Complexity:
    • Adjacency List: O(V+E)O(V + E) (each vertex and edge is examined at most twice in undirected graphs).
    • Adjacency Matrix: O(V2)O(V^2) (scanning row for each vertex requires O(V)O(V) operations).
  • Space Complexity: O(V)O(V) auxiliary space for the recursion call stack and the mark[] array.

4.5 Iterative DFS Algorithm (Using Stack)​

💡 The Big Idea in Plain English​

Recursive DFS uses the computer's internal call stack behind the scenes. Iterative DFS does the exact same thing, but uses an explicit Stack data structure (Last-In, First-Out: LIFO) that you control! Think of a stack of cafeteria trays: You push the start node onto the stack. Then you repeatedly pop the top tray off, visit it, and push all its unvisited neighbors onto the top of the stack. Because the latest neighbor is always on top, you naturally explore deep before going wide!

👣 3 Easy Steps to Remember​

  1. Push the Start Vertex: Create an empty stack SS and push start node ss onto it. Set all nodes as unvisited.
  2. Pop and Process:
    • While stack SS is not empty:
    • Pop the top node uu.
    • If uu is not visited yet: mark it as visited and process it!
  3. Push Its Neighbors:
    • Look at all neighbors of uu. Push every unvisited neighbor onto stack SS.
    • Repeat until the stack is completely empty!

🧠 Memory Trick: Stack (LIFO) →\to Push start →\to Pop top →\to If unvisited: mark visited and push neighbors. Simulates recursion without stack overflow risks! Runs in O(V+E)O(V + E) time.

5. Breadth First Search (BFS)​

5.1 Concept and Queue Mechanism​

Breadth First Search (BFS) explores a graph level by level (layer by layer), visiting all neighbors of a node before moving to vertices at the next depth level. It utilizes a First-In, First-Out (FIFO) Queue.

Core Traversal Rules
  1. Select any node v∈Nv \in N as the starting point and mark it as visited.
  2. Enqueue visited node vv into queue QQ.
  3. While queue QQ is not empty:
    • Dequeue node uu from the front of QQ.
    • Find all unvisited adjacent nodes of uu, mark them as visited, and enqueue them into QQ.
  4. If any nodes remain unvisited, restart BFS on the next unvisited vertex.

5.2 BFS Algorithm Pseudocode​

💡 The Big Idea in Plain English​

Think of dropping a pebble into calm water: Ripples spread outward layer by layer, circle by circle. BFS explores a graph the exact same way: it visits all immediate neighbors first (1 step away), then all secondary neighbors (2 steps away), and so forth. To process vertices in the exact order they were discovered, it uses a FIFO Queue (First-In, First-Out — like a real-life queue at a ticket counter)!

👣 3 Easy Steps to Remember​

  1. Line Up the Start Node: Mark start node vv as visited and push it into queue QQ.
  2. Process the Front of the Line:
    • While queue QQ is not empty:
    • Pull the first node uu out of the front (dequeue).
  3. Enqueue All Unvisited Neighbors:
    • Check every neighbor ww directly connected to uu.
    • If ww is not visited yet: mark it visited and push it to the back of the queue!
    • Repeat until no nodes are left in the queue.

🧠 Memory Trick: FIFO Queue →\to Enqueue start →\to Pop front →\to Enqueue all unvisited neighbors! Explores layer-by-layer. Guaranteed to find the shortest path in unweighted graphs. Time: O(V+E)O(V + E).

5.3 Step-by-Step Execution and Trace Example​

Tracing BFS on the same 8-node graph starting from node 1:

StepActionDequeued NodeUnvisited Adjacent Nodes EnqueuedQueue State (QQ)
0Start-Mark 1 visited, Enqueue 1[1]
1Dequeue & Explore1Neighbors 2, 3, 4 marked visited and enqueued[2, 3, 4]
2Dequeue & Explore2Neighbors 5, 6 marked visited and enqueued[3, 4, 5, 6]
3Dequeue & Explore3Neighbor 6 is already visited; none added[4, 5, 6]
4Dequeue & Explore4Neighbors 7, 8 marked visited and enqueued[5, 6, 7, 8]
5Dequeue & Explore5No unvisited neighbors[6, 7, 8]
6Dequeue & Explore6No unvisited neighbors[7, 8]
7Dequeue & Explore7Neighbor 8 already visited[8]
8Dequeue & Explore8No unvisited neighbors[] (Empty, finishes)
  • Final Visited Sequence: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8

5.4 Complexity and Properties​

  • Time Complexity:
    • Adjacency List: O(V+E)O(V + E)
    • Adjacency Matrix: O(V2)O(V^2)
  • Space Complexity: O(V)O(V) for the queue QQ and visited lookup array.
  • Shortest Path Property: In an unweighted graph, BFS is guaranteed to discover the shortest path (minimum edge count) from the start node to all other reachable nodes.

5.5 Queue-Based BFS Traversal Algorithm​

💡 The Big Idea in Plain English​

In academic textbooks (like CLRS), BFS tracks progress using three simple traffic-light colors:

  • ⚪ WHITE: Unseen / untouched (distance is unknown: ∞\infty).
  • 🔘 GRAY: Discovered and currently waiting in line (in the queue).
  • ⚫ BLACK: Completely finished (all neighbors have been fully explored). As each node is visited, it calculates its exact step-count distance from the start (d[v]=d[u]+1d[v] = d[u] + 1), giving you the shortest path in unweighted graphs!

👣 3 Easy Steps to Remember​

  1. Paint and Prepare:
    • Paint every node WHITE and set distance to ∞\infty.
    • Paint start node ss GRAY, set d[s]=0d[s] = 0, and put it in queue QQ.
  2. Process Front of the Line:
    • While queue QQ is not empty, pull out node uu (DEQUEUE).
  3. Discover White Neighbors:
    • Check every neighbor vv of uu:
    • If vv is WHITE (untouched):
      • Paint it GRAY (mark discovered).
      • Set distance: d[v]=d[u]+1d[v] = d[u] + 1.
      • Set predecessor: parent[v]=uparent[v] = u.
      • Put vv into queue QQ!
    • When finished checking all neighbors of uu, paint uu BLACK (done!).

🧠 Memory Trick: White (unseen) →\to Gray (in queue, d=d+1d = d+1) →\to Black (done)! Level-by-level shortest path traversal running in O(V+E)O(V + E) time.

6. Graph Traversal Comparison: DFS vs BFS​

6.1 Comparative Walkthrough Example​

Consider the 6-vertex graph below:

Starting from vertex A and ordering adjacent nodes alphabetically:

  • DFS Traversal Order: A -> B -> D -> C -> E -> F
    • Explores branch: A→B→D→C→E→FA \to B \to D \to C \to E \to F to maximum depth.
  • BFS Traversal Order: A -> B -> C -> D -> E -> F
    • Level 0: AA
    • Level 1: B,CB, C
    • Level 2: D,E,FD, E, F

6.2 Key Differences Summary​

FeatureDepth First Search (DFS)Breadth First Search (BFS)
Core PhilosophyGoes deep along one path before backtrackingExplores all immediate neighbors level-by-level
Primary Data StructureLIFO Stack (call stack or explicit stack)FIFO Queue
Shortest PathDoes not find shortest path in unweighted graphsGuarantees shortest path in unweighted graphs
Memory ConsumptionO(height)O(\text{height}), proportional to graph depthO(breadth)O(\text{breadth}), proportional to maximum layer size
BacktrackingInnate feature of the recursive approachNo backtracking mechanism needed
Typical ApplicationsTopological sort, cycle detection, strongly connected components, maze solvingShortest path, web crawling, peer-to-peer networks, garbage collection

7. Topological Sorting​

7.1 Concept and Conditions (DAG)​

A Topological Sort (or topological ordering) of a Directed Acyclic Graph (DAG) is a linear ordering of its vertices such that for every directed edge (u,v)(u, v) from vertex uu to vertex vv, uu precedes vv in the ordering:

(u,v)∈E  ⟹  position(u)<position(v)(u, v) \in E \implies \text{position}(u) < \text{position}(v)
DAG Prerequisite

Topological sort is only possible on Directed Acyclic Graphs. If the graph contains any directed cycle, no linear dependency ordering exists because circular dependencies cannot be resolved.

7.2 Real-World Analogy: Recipe Preparation​

Preparing pancakes requires dependencies to be completed in order:

  • Ingredients (milk, egg, oil) must be combined into mix before pouring.
  • Griddle must be heated before pouring mix.
  • Pancake must be turned when bubbly before eating.
  • Syrup must be heated before eating.

7.3 Algorithms for Topological Sorting​

7.3.1 Kahn's Algorithm (In-degree Elimination Method)​

  1. Compute the in-degree for every vertex in the graph.
  2. Initialize a queue with all vertices having an in-degree of 0 (no prerequisites).
  3. While the queue is not empty:
    • Dequeue a vertex uu and append it to the topological output.
    • For each outgoing edge (u,v)(u, v), decrement the in-degree of vv by 1.
    • If the in-degree of vv drops to 0, enqueue vv.
  4. If the count of visited vertices is less than ∥V∥\|V\|, the graph contains a cycle.

7.3.2 DFS-Based Approach​

  1. Perform standard DFS traversal.
  2. When all outgoing neighbors of a vertex uu have finished processing (post-visit), push uu onto a stack.
  3. After completing DFS for all vertices, pop elements from the stack to produce the topological ordering.

7.4 Trace Examples​

7.4.1 Example 1 (Alphabetical Graph)​

Given DAG with vertices {A,B,C,D,E,F}\{A, B, C, D, E, F\} and edges:

  • A→BA \to B, A→DA \to D
  • B→CB \to C
  • C→DC \to D, C→EC \to E
  • D→ED \to E
  • FF (independent node, in-degree 0)
  1. Vertices with in-degree 0: AA and FF.
  2. Select AA, remove its edges (A,B)(A, B) and (A,D)(A, D). Output: [A]
  3. Next BB has in-degree 0, remove (B,C)(B, C). Output: [A, B]
  4. Next CC has in-degree 0, remove (C,D)(C, D) and (C,E)(C, E). Output: [A, B, C]
  5. Next DD has in-degree 0, remove (D,E)(D, E). Output: [A, B, C, D]
  6. Next EE has in-degree 0. Output: [A, B, C, D, E]
  7. Node FF has in-degree 0. Output: [A, B, C, D, E, F]
  • Topological Order: A B C D E F

7.4.2 Example 2 (Numerical Graph)​

Given DAG with vertices {0,1,2,3,4,5}\{0, 1, 2, 3, 4, 5\} and edges:

  • 5→25 \to 2, 5→05 \to 0
  • 4→04 \to 0, 4→14 \to 1
  • 2→32 \to 3
  • 3→13 \to 1

In-Degree Table:

  • 0: 2 (from 4, 5)
  • 1: 2 (from 3, 4)
  • 2: 1 (from 5)
  • 3: 1 (from 2)
  • 4: 0
  • 5: 0

Step-by-Step Elimination:

  1. Remove 4 (in-degree 0): decrements in-degree of 0 to 1, and 1 to 1.
  2. Remove 5 (in-degree 0): decrements in-degree of 2 to 0, and 0 to 0.
  3. Remove 0 (in-degree 0).
  4. Remove 2 (in-degree 0): decrements in-degree of 3 to 0.
  5. Remove 3 (in-degree 0): decrements in-degree of 1 to 0.
  6. Remove 1 (in-degree 0).
  • Final Output Sequence: 4 5 0 2 3 1

7.5 Complexity Analysis​

  • Time Complexity: O(V+E)O(V + E) (calculating in-degrees takes O(V+E)O(V + E) and each vertex/edge is processed once).
  • Space Complexity: O(V)O(V) for the in-degree array, queue/stack, and output array.

7.6 Kahn's Topological Sorting Algorithm​

💡 The Big Idea in Plain English​

Think of university course prerequisites or building software from source: You cannot take "Advanced Algorithms" until you complete "Data Structures", and you can't take "Data Structures" without "Intro to Programming"! In graph terms, the in-degree of a node is simply its number of unmet prerequisites (incoming arrows). Kahn's rule is common sense:

  1. Always start with tasks that have zero prerequisites (in-degree = 0).
  2. Once you complete a task, cross it off and decrement the prerequisite count for all tasks that depended on it.
  3. Whenever a dependent task reaches 0 remaining prerequisites, it's ready to be worked on! If you ever get stuck with tasks remaining but none have 0 prerequisites, there is a circular deadlock (a cycle)!

👣 3 Easy Steps to Remember​

  1. Count Prerequisites (In-Degrees): Count incoming edges for every vertex.
  2. Queue Ready Tasks: Put all vertices with inDegree == 0 into a queue.
  3. Process & Unlock Next Tasks:
    • While the queue is not empty:
    • Pop node uu and add it to your schedule (order).
    • For each outgoing neighbor vv: decrease its prerequisite count (inDegree[v] - 1).
    • If inDegree[v] == 0: all prerequisites are satisfied →\to put vv into the queue!
  4. Cycle Detection: If the count of processed nodes <∣V∣< |V|, a cycle exists (topological order is impossible)! Otherwise, return the order.

🧠 Memory Trick: Count incoming arrows →\to Queue nodes with 0 arrows →\to Pop node, subtract 1 from neighbors →\to If 0, push into queue! Runs in O(V+E)O(V + E) time. Only works on DAGs.

8. Connected Components​

8.1 Connected Components in Undirected Graphs​

A connected component (or component) of an undirected graph is a maximal subgraph in which any two vertices are connected to each other by paths.

  • In the example above, the graph has vertices {0,1,2,3,4}\{0, 1, 2, 3, 4\}.
  • There are two connected components:
    1. Component 1: Vertices 0, 1, 2
    2. Component 2: Vertices 3, 4

8.2 Strongly Connected Components (SCC) in Directed Graphs​

In a directed graph, connectivity has two forms:

  1. Strongly Connected Component (SCC): A maximal subgraph where every vertex is reachable from every other vertex in the subgraph (u→vu \to v and v→uv \to u paths both exist).
  2. Weakly Connected Component: A subgraph that is connected if all directed edges are replaced with undirected edges.

Algorithms to compute SCCs in O(V+E)O(V + E) time:

  • Kosaraju's Algorithm: Two DFS passes (first on GG, second on transpose graph GTG^T).
  • Tarjan's Algorithm: Single DFS pass maintaining discovery times and a stack.

8.3 Computing Connected Components​

  • Iterate through all vertices v∈Vv \in V.
  • If vv is not yet visited, initiate a DFS or BFS traversal from vv.
  • Every vertex discovered during that traversal belongs to the same connected component.
  • Increment the component counter and continue.
  • Time Complexity: O(V+E)O(V + E)
  • Space Complexity: O(V)O(V)

💡 The Big Idea in Plain English​

Think of discovering separate groups of islands across an ocean: Some islands are connected by bridges (forming an island cluster), while others are completely isolated across the water. To count and list every separate cluster: You walk through the entire list of islands. If you spot an island you haven't visited yet, you've found a brand-new cluster! You immediately cross every bridge attached to it (using DFS or BFS) and paint every reachable island in that group. Once you run out of bridges, you continue scanning the map for the next unpainted island!

👣 3 Easy Steps to Remember​

  1. Reset All Flags: Mark every vertex in the graph as visited = false.
  2. Scan All Vertices:
    • For each vertex vv in the graph:
    • If vv is not visited:
      • Increment componentId (you found a new island cluster!).
      • Launch DFSComponent(v) to visit and print every vertex in this connected component.
  3. Finish: Once every vertex is marked, all disconnected groups are identified.

🧠 Memory Trick: Loop all nodes →\to Hit unvisited node? Start new component →\to Launch DFS to tag the entire cluster! Runs in O(V+E)O(V + E) time.

9. Articulation Points (Cut Vertices)​

9.1 Concept and Vulnerability in Networks​

  • An articulation point (or cut vertex) in a connected graph is a vertex whose removal (along with all its incident edges) disconnects the graph (increases the number of connected components).
  • Cybersecurity & Network Relevance: Articulation points represent critical Single Points of Failure (SPOFs). If an attacker disables an articulation node (or router), the entire network fragments into isolated segments.

9.2 Conditions for Articulation Points (Tarjan's DFS Tree)​

Using DFS traversal, we assign two values to every vertex uu:

  • disc[u]: Discovery time when node uu is first visited.
  • low[u]: Lowest discovery time reachable from uu through tree edges and at most one back-edge.

A vertex uu is an articulation point if:

  1. Root Condition: uu is the root of the DFS tree and has two or more independent children in the DFS tree.
  2. Non-Root Condition: uu is not the root of the DFS tree, and has a child vv such that: low[v]≥disc[u]low[v] \ge disc[u] (This signifies that no vertex in the subtree rooted at vv has a back-edge to any proper ancestor of uu. Thus, removing uu traps vv and isolates the subtree).

9.3 Examples Walkthrough​

9.3.1 Example 1​

Vertices: {1,2,3,4,5}\{1, 2, 3, 4, 5\} with edges:

  • Triangle: (1,4),(1,2),(4,2)(1, 4), (1, 2), (4, 2)
  • Bridge edges: (2,3)(2, 3) and (3,5)(3, 5)
  • Articulation Points: 2, 3
  • Analysis:
    • Removing vertex 2 splits the graph into {1,4}\{1, 4\} and {3,5}\{3, 5\}.
    • Removing vertex 3 isolates vertex 5 from the rest of the graph.
    • Removing vertices 1, 4, or 5 leaves the remaining vertices connected.

9.3.2 Example 2​

Vertices: {1,2,3,4,5,6,7}\{1, 2, 3, 4, 5, 6, 7\} with edges:

  • Triangle: (1,2),(1,3),(2,3)(1, 2), (1, 3), (2, 3)
  • Leaf node attached: (3,4)(3, 4)
  • Diamond component: (3,5),(3,6),(5,7),(6,7)(3, 5), (3, 6), (5, 7), (6, 7)
  • Articulation Points: 3
  • Analysis:
    • Vertex 3 is the central nexus connecting 3 distinct groups: {1,2}\{1, 2\}, {4}\{4\}, and {5,6,7}\{5, 6, 7\}.
    • Removing vertex 3 divides the graph into 3 separate disconnected components.
    • No other individual vertex deletion disconnects the graph.

9.4 Complexity Analysis​

  • Time Complexity: O(V+E)O(V + E) (a single DFS traversal).
  • Space Complexity: O(V)O(V) auxiliary arrays for disc[], low[], parent[], and recursion stack.

9.5 Articulation Points Algorithm (Tarjan's DFS)​

💡 The Big Idea in Plain English​

An articulation point (cut vertex) is a critical vulnerability or bottleneck: if this single node crashes, the graph splits into disconnected pieces! In networks, these are dangerous Single Points of Failure (SPOFs). Tarjan's algorithm detects all cut vertices in a single DFS walk using two simple numbers per node uu:

  • disc[u]: When DFS first stepped onto node uu (discovery clock).
  • low[u]: The highest ancestor (smallest discovery time) that uu or its descendants can reach using a shortcut / back-edge.

A node uu is an articulation point in two simple scenarios:

  1. If uu is the Root of the DFS tree: It has 2 or more separate children (removing root disconnects them).
  2. If uu is Any Other Node: It has a child vv where low[v]≥disc[u]low[v] \ge disc[u]. This proves child vv has no backdoor path to reach the rest of the network without going through uu! If uu fails, vv is stranded!

👣 3 Easy Steps to Remember​

  1. Set Discovery Timers: On entering node uu, set disc[u] = low[u] = ++timer.
  2. Explore Neighbors:
    • If neighbor vv is already visited (a cycle/back-edge): update low[u]=min⁡(low[u],disc[v])low[u] = \min(low[u], disc[v]).
    • If neighbor vv is unvisited: increment children, call DFS(v), then pull back low[u]=min⁡(low[u],low[v])low[u] = \min(low[u], low[v]).
  3. Test the Two Rules:
    • Rule 1 (Root node): parent == NIL and children > 1   ⟹  \implies uu is a cut vertex!
    • Rule 2 (Non-root): parent != NIL and low[v]≥disc[u]low[v] \ge disc[u]   ⟹  \implies uu is a cut vertex!

🧠 Memory Trick: Root with ≥2\ge 2 children OR Non-root whose child has low[v]≥disc[u]low[v] \ge disc[u] (no backdoor shortcut). Discovered in a single DFS pass in O(V+E)O(V + E) time!

10. Summary and Quick Revision Cheat Sheet​

10.1 Graph Algorithm Complexity Master Table​

AlgorithmPrimary Data StructureGraph CompatibilityTime ComplexitySpace ComplexityPrimary Use Case
DFSLIFO Stack (call stack)Directed & UndirectedO(V+E)O(V + E)O(V)O(V)Connectivity, cycle detection, path finding
BFSFIFO QueueDirected & UndirectedO(V+E)O(V + E)O(V)O(V)Shortest path in unweighted graphs, level order
Topological SortIn-degree array + Queue / StackDAG onlyO(V+E)O(V + E)O(V)O(V)Task scheduling, dependency resolution, build systems
Connected ComponentsVisited array + DFS/BFSUndirected GraphsO(V+E)O(V + E)O(V)O(V)Network partitioning, cluster discovery
Articulation PointsDFS Tree (disc[], low[])Connected UndirectedO(V+E)O(V + E)O(V)O(V)Single Point of Failure (SPOF) identification

10.2 Formula and Rule Quick-Sheet​

  • Graph Formal Definition: G=⟨N,A⟩G = \langle N, A \rangle, where NN is the set of nodes and AA is the set of edges.
  • Topological Condition: Directed Acyclic Graph (DAG) only. If in-degree 0 vertices vanish before all vertices are visited, a cycle exists.
  • Articulation Point Conditions:
    • Root: ≥2\ge 2 children in DFS tree.
    • Non-root: Child vv satisfies low[v]≥disc[u]low[v] \ge disc[u].