G27
Self-checkedTier 1 15 min readalgo.dfs-classification

DFS edge types, topological sort and SCC

What a depth-first search of a directed graph reveals: the four kinds of edges (tree, back, forward, cross) decided by colours and times, that a directed graph has a cycle exactly when there is a back edge, topological sorting of a DAG by decreasing finish time and by Kahn's algorithm (and when the order is unique), and strongly connected components by Kosaraju's two searches.

Why it exists

A depth-first search of a directed graph does more than visit the vertices: the kind of every edge it meets carries information. A back edge means a cycle; no back edge means the graph is a DAG (directed acyclic graph), and then the order in which the vertices finish gives a topological order, the way to schedule tasks that depend on each other. Running the search twice, on the graph and on its reversal, splits any graph into its strongly connected components. These three results (cycle detection, topological sort, SCC) are standard GATE material.

Prerequisites

You need depth-first search with colours and discovery and finish times (BFS and DFS).

Precise definitions

Directed graph. Edges u→vu \to v have a direction. Adjacency lists hold only the edges that leave a vertex.

Edge types of a depth-first forest, for an edge u→vu \to v:

  • Tree edge: the search reaches vv for the first time through this edge (vv is white when the edge is examined).
  • Back edge: vv is an ancestor of uu (or uu itself, a self-loop): vv is gray.
  • Forward edge: vv is a descendant of uu but the edge is not a tree edge: vv is already black and was discovered after uu.
  • Cross edge: every other edge: vv is black and was discovered before uu, in another branch or another tree.

Directed acyclic graph (DAG). A directed graph with no directed cycle.

Topological order. A list of all vertices in which every edge u→vu \to v has uu before vv. It exists exactly for DAGs.

Strongly connected. Two vertices uu and vv are in the same strongly connected component (SCC) if there is a path from uu to vv and a path from vv to uu. The components partition the vertices; contracting each to a point gives the component graph, which is always a DAG.

How it works

Classifying edges

The animation runs the real code on a directed graph with 88 vertices and 1111 edges. The kind of each edge is chosen by the same four lines that the page shows: white means tree, gray means back, black means forward if d[u]<d[v]d[u] < d[v] and cross otherwise.

Depth-first search on a directed graph: classifying every edge

Real run

C source

1#include <stdio.h>
2
3#define N 8
4enum { WHITE, GRAY, BLACK };
5
6static int deg[N];
7static int nbr[N][N]; /* nbr[u]: the targets of the edges that leave u */
8static int color[N], parent[N], disc[N], fin[N], timer;
9
10void dfs_visit(int u) {
11 color[u] = GRAY;
12 disc[u] = ++timer;
13 for (int k = 0; k < deg[u]; k++) {
14 int v = nbr[u][k];
15 const char *kind;
16 if (color[v] == WHITE) {
17 kind = "tree";
18 } else if (color[v] == GRAY) {
19 kind = "back";
20 } else if (disc[u] < disc[v]) {
21 kind = "forward";
22 } else {
23 kind = "cross";
24 }
25 if (kind[0] == 't') { /* only tree edges are followed */
26 parent[v] = u;
27 dfs_visit(v);
28 }
29 }
30 color[u] = BLACK;
31 fin[u] = ++timer;
32}
33
34void dfs(void) {
35 for (int v = 0; v < N; v++) {
36 color[v] = WHITE;
37 parent[v] = -1;
38 }
39 timer = 0;
40 for (int v = 0; v < N; v++) {
41 if (color[v] == WHITE) {
42 dfs_visit(v);
43 }
44 }
45}

color (W = white, G = gray, B = black)

W
0
W
1
W
2
W
3
W
4
W
5
W
6
W
7

discovery time disc[v]

0
1
2
3
4
5
6
7

finish time fin[v]

0
1
2
3
4
5
6
7

recursion stack (top on the right)

bottomempty

Adjacency lists (edges leave the vertex)

0→1→3→ NULL
1→2→ NULL
2→0→3→ NULL
3→4→ NULL
4→5→ NULL
5→3→ NULL
6→5→7→ NULL
7→6→ NULL

Edges classified so far

none yet

Blue = the position this step is working on, amber = a position being compared, red = positions just swapped, green = finished or in its final place, a filled blue cell = a value just placed, faded = not part of the structure at this step.

Step 1

Depth-first search on a directed graph: three strongly connected groups, {0, 1, 2}, {3, 4, 5} and {6, 7}.

1 / 31
A directed graph with 8 vertices and 11 edges is set up by hidden driver code (each list is in increasing order). dfs_visit() is the exact code that runs; the kind of each edge is decided from the colour of its far end and the discovery times. Produced by: real execution: every array, stack, matrix and list in the picture is read from the running program's memory at each step. Apple clang version 21.0.0 (clang-2100.1.1.101). gcc -O0 -o prog prog.c && ./prog

The program prints every edge with its kind and then, further down, the times and the strongly connected components of this graph.

#include <stdio.h>
 
#define N 8
 
static int deg[N], nbr[N][N];                /* edges that leave each vertex, in increasing order */
static int tdeg[N], tnbr[N][N];              /* the reversed graph */
 
enum { WHITE, GRAY, BLACK };
static int color[N], disc[N], fin[N], timer, finish_order[N], nfin;
 
static void dfs_visit(int u, int print) {
    color[u] = GRAY;
    disc[u] = ++timer;
    for (int k = 0; k < deg[u]; k++) {
        int v = nbr[u][k];
        const char *kind;
        if (color[v] == WHITE) kind = "tree";
        else if (color[v] == GRAY) kind = "back";
        else if (disc[u] < disc[v]) kind = "forward";
        else kind = "cross";
        if (print) printf("edge %d -> %d %s\n", u, v, kind);
        if (color[v] == WHITE) dfs_visit(v, print);
    }
    color[u] = BLACK;
    fin[u] = ++timer;
    finish_order[nfin++] = u;
}
 
static int comp[N];
static void collect(int u, int c) {              /* a depth-first search in the reversed graph */
    comp[u] = c;
    for (int k = 0; k < tdeg[u]; k++) if (comp[tnbr[u][k]] < 0) collect(tnbr[u][k], c);
}
 
int main(void) {
    int E[11][2] = {{0, 1}, {0, 3}, {1, 2}, {2, 0}, {2, 3}, {3, 4}, {4, 5}, {5, 3}, {6, 5}, {6, 7}, {7, 6}};
    for (int i = 0; i < 11; i++) { nbr[E[i][0]][deg[E[i][0]]++] = E[i][1]; tnbr[E[i][1]][tdeg[E[i][1]]++] = E[i][0]; }
    for (int v = 0; v < N; v++) if (color[v] == WHITE) dfs_visit(v, 1);
    printf("times (disc/fin):");
    for (int v = 0; v < N; v++) printf(" %d:%d/%d", v, disc[v], fin[v]);
    printf("\nfinish order:");
    for (int i = 0; i < nfin; i++) printf(" %d", finish_order[i]);
    printf("\n");
    for (int v = 0; v < N; v++) comp[v] = -1;
    int count = 0;
    for (int i = N - 1; i >= 0; i--) {                       /* decreasing finish time */
        int r = finish_order[i];
        if (comp[r] < 0) {
            collect(r, count);
            printf("component %d (root %d):", count, r);
            for (int v = 0; v < N; v++) if (comp[v] == count) printf(" %d", v);
            printf("\n");
            count++;
        }
    }
    printf("%d strongly connected components\n", count);
    return 0;
}
edge 0 -> 1 tree
edge 1 -> 2 tree
edge 2 -> 0 back
edge 2 -> 3 tree
edge 3 -> 4 tree
edge 4 -> 5 tree
edge 5 -> 3 back
edge 0 -> 3 forward
edge 6 -> 5 cross
edge 6 -> 7 tree
edge 7 -> 6 back
times (disc/fin): 0:1/12 1:2/11 2:3/10 3:4/9 4:5/8 5:6/7 6:13/16 7:14/15
finish order: 5 4 3 2 1 0 7 6
component 0 (root 6): 6 7
component 1 (root 0): 0 1 2
component 2 (root 3): 3 4 5
3 strongly connected components

Every edge of a directed graph classified by depth-first search: start

Computed by a script, not typed
edgekindtimes of the start u (disc/fin)times of the end v (disc/fin)why
0 -> 1
1 -> 2
2 -> 0
2 -> 3
3 -> 4
4 -> 5
5 -> 3
0 -> 3
6 -> 5
6 -> 7
7 -> 6

Step 0

A depth-first search of a directed graph with 8 vertices and 11 edges. The kind of an edge u -> v depends on the colour of v when the edge is examined: white = tree, gray = back, black = forward (if v was discovered after u) or cross (if before).

0 / 11
computed by script: the quantities are measured by running C, or evaluated, one row at a time. python3 scripts/gen-algo-graph-traces.py

The same facts in terms of the time stamps (all four kinds can be recognised afterwards from the intervals): for u→vu \to v

KindIntervalsCondition when examined
tree, forwardd[u]<d[v]<f[v]<f[u]d[u] < d[v] < f[v] < f[u]vv white (tree) or black with d[u]<d[v]d[u] < d[v] (forward)
backd[v]≤d[u]<f[u]≤f[v]d[v] \le d[u] < f[u] \le f[v]vv gray
crossf[v]<d[u]f[v] < d[u]vv black, d[v]<d[u]d[v] < d[u]

Consequences.

  1. In a depth-first search of an undirected graph every edge is a tree edge or a back edge (forward edges are the same edges seen from the other end); there are no cross edges.
  2. A directed graph has a cycle if and only if the search finds a back edge. (A back edge u→vu \to v closes the cycle v⇝u→vv \leadsto u \to v along the tree path; conversely, a cycle has a first vertex discovered, and the vertex before it on the cycle becomes its descendant by the white-path theorem and gives a back edge.)
  3. In a DAG, for every edge u→vu \to v we have f[u]>f[v]f[u] > f[v].

Topological sort

By depth-first search. Run DFS, and write the vertices in decreasing finish time (put each vertex at the front of a list when it finishes). By fact 3 every edge goes from a vertex that finishes later to one that finishes earlier, so it points forward in the list. Time Θ(V+E)\Theta(V + E).

Kahn's algorithm. Repeatedly remove a vertex with in-degree 00 and delete its outgoing edges (decreasing the in-degrees of its targets), appending the removed vertices in order. If the graph has a cycle the algorithm gets stuck with vertices left over (all remaining in-degrees positive): this is also a cycle test. Time Θ(V+E)\Theta(V + E).

A DAG usually has many topological orders. The program below computes the order from DFS, Kahn's order (always taking the smallest available vertex), and counts all valid orders by trying every permutation of the 88 vertices.

#include <stdio.h>
 
#define N 8
 
static int deg[N], nbr[N][N], indeg[N];
 
enum { WHITE, GRAY, BLACK };
static int color[N], order[N], pos;
 
static void dfs_visit(int u) {
    color[u] = GRAY;
    for (int k = 0; k < deg[u]; k++) if (color[nbr[u][k]] == WHITE) dfs_visit(nbr[u][k]);
    color[u] = BLACK;
    order[--pos] = u;                              /* a vertex is put in front of everything finished before it */
}
 
static int valid(const int p[]) {                  /* every edge goes from an earlier to a later vertex */
    int at[N];
    for (int i = 0; i < N; i++) at[p[i]] = i;
    for (int u = 0; u < N; u++) for (int k = 0; k < deg[u]; k++) if (at[u] > at[nbr[u][k]]) return 0;
    return 1;
}
 
static long count_orders(int p[], int used, int k) {   /* tries every permutation */
    if (k == N) return valid(p);
    long total = 0;
    for (int v = 0; v < N; v++) if (!(used >> v & 1)) { p[k] = v; total += count_orders(p, used | 1 << v, k + 1); }
    return total;
}
 
int main(void) {
    int E[9][2] = {{0, 1}, {0, 2}, {1, 3}, {2, 3}, {2, 5}, {3, 4}, {5, 4}, {6, 2}, {6, 7}};
    for (int i = 0; i < 9; i++) { nbr[E[i][0]][deg[E[i][0]]++] = E[i][1]; indeg[E[i][1]]++; }
    pos = N;
    for (int v = 0; v < N; v++) if (color[v] == WHITE) dfs_visit(v);
    printf("DFS order (decreasing finish time):");
    for (int i = 0; i < N; i++) printf(" %d", order[i]);
    printf("  valid: %s\n", valid(order) ? "yes" : "no");
    int kahn[N], done = 0, d[N];
    for (int v = 0; v < N; v++) d[v] = indeg[v];
    while (done < N) {                             /* Kahn: repeatedly remove the smallest vertex of in-degree 0 */
        int u = -1;
        for (int v = 0; v < N; v++) {
            int taken = 0;
            for (int i = 0; i < done; i++) if (kahn[i] == v) taken = 1;
            if (!taken && d[v] == 0) { u = v; break; }
        }
        kahn[done++] = u;
        for (int k = 0; k < deg[u]; k++) d[nbr[u][k]]--;
    }
    printf("Kahn order (smallest in-degree-0 vertex first):");
    for (int i = 0; i < N; i++) printf(" %d", kahn[i]);
    printf("  valid: %s\n", valid(kahn) ? "yes" : "no");
    int p[N];
    printf("number of different topological orders: %ld\n", count_orders(p, 0, 0));
    return 0;
}
DFS order (decreasing finish time): 6 7 0 2 5 1 3 4  valid: yes
Kahn order (smallest in-degree-0 vertex first): 0 1 6 2 3 5 4 7  valid: yes
number of different topological orders: 75

Two topological orders of a DAG (there are 75 in all): start

Computed by a script, not typed
methodordervalid (checked)
DFS: decreasing finish time
Kahn: remove in-degree 0 vertices

Step 0

The DAG has the edges 0->1, 0->2, 1->3, 2->3, 2->5, 3->4, 5->4, 6->2, 6->7. A topological order lists every vertex before the vertices it points to. A program tried all 8! permutations and counted 75 valid ones.

0 / 2
computed by script: the quantities are measured by running C, or evaluated, one row at a time. python3 scripts/gen-algo-graph-traces.py

When is the order unique? Exactly when the DAG has a path through all vertices, that is, when consecutive vertices in the order are joined by edges (checked on 300 random DAGs). Otherwise there are at least two orders.

Strongly connected components (Kosaraju)

  1. Run DFS on GG and record the finish times.
  2. Build the reversed graph GTG^{T} (all edges turned round). It has the same strongly connected components.
  3. Run DFS on GTG^{T}, starting new trees from the vertices in decreasing finish time (of step 1). Each tree of this second search is one strongly connected component.

Why: in GG, the component that contains the vertex with the largest finish time is a source of the component graph (nothing enters it from another component); in GTG^T it is a sink, so the search started there cannot leave it. Remove it and repeat. The components come out in a topological order of the component graph. Time Θ(V+E)\Theta(V + E). (Tarjan's algorithm finds the components in one search using low-link values.)

Strongly connected components by two depth-first searches (Kosaraju): start

Computed by a script, not typed
pass 2 startroot (largest unassigned finish time)vertices of the component
component 0
component 1
component 2

Step 0

The first search (table above) gave the finish order 5 4 3 2 1 0 7 6. The second pass takes the vertices in decreasing finish time and searches in the reversed graph; each search finds one component.

0 / 3
computed by script: the quantities are measured by running C, or evaluated, one row at a time. python3 scripts/gen-algo-graph-traces.py

The graph has three components: {6,7}\{6, 7\} (a 22-cycle, with an edge 6→56 \to 5 leaving it), {0,1,2}\{0, 1, 2\} (a 33-cycle, with edges to 33) and {3,4,5}\{3, 4, 5\} (a 33-cycle). The component graph {6,7}→{3,4,5}\{6,7\} \to \{3,4,5\} and {0,1,2}→{3,4,5}\{0,1,2\} \to \{3,4,5\} is a DAG, and the components were found in an order consistent with it ({6,7}\{6, 7\}, then {0,1,2}\{0, 1, 2\}, then {3,4,5}\{3, 4, 5\}).

Worked examples

EX 1Classify the edges by hand

Easy

Directed graph 1→21 \to 2, 1→31 \to 3, 2→42 \to 4, 3→43 \to 4, 4→14 \to 1. DFS from 11 (neighbours in increasing order): 11 (d=1d = 1), edge 1→21 \to 2 white: tree; 22 (d=2d = 2), edge 2→42 \to 4 white: tree; 44 (d=3d = 3), edge 4→14 \to 1: 11 is gray: back edge (a cycle 1→2→4→11 \to 2 \to 4 \to 1); 44 finishes (44), 22 finishes (55); back at 11: edge 1→31 \to 3 white: tree; 33 (d=6d = 6), edge 3→43 \to 4: 44 is black and was discovered before 33 (3<63 < 6): cross edge; 33 finishes (77), 11 finishes (88). The graph is not a DAG (it has a back edge).

EX 2Topological order by finish times

Easy

DAG with edges A→BA \to B, A→CA \to C, B→DB \to D, C→DC \to D. DFS from AA, neighbours in order: AA (1), BB (2), DD (3), DD finishes (4), BB finishes (5), CC (6): the edge C→DC \to D leads to black DD; CC finishes (7), AA finishes (8). Decreasing finish time: A,C,B,DA, C, B, D. Check: A→BA \to B, A→CA \to C, B→DB \to D, C→DC \to D all go forward. Another valid order is A,B,C,DA, B, C, D (Kahn); there are exactly 22.

EX 3Kahn's algorithm detects a cycle

Medium

Edges 1→21 \to 2, 2→32 \to 3, 3→13 \to 1, 4→14 \to 1. In-degrees: 11: 22 (from 33 and 44), 22: 11, 33: 11, 44: 00. Remove 44: the in-degree of 11 drops to 11. Nothing has in-degree 00 any more, but vertices 1,2,31, 2, 3 are left: the algorithm stops early, so the graph has a cycle (here 1→2→3→11 \to 2 \to 3 \to 1).

EX 4How many strongly connected components?

Medium

Graph on {1,…,5}\{1, \ldots, 5\} with edges 1→21 \to 2, 2→12 \to 1, 2→32 \to 3, 3→43 \to 4, 4→54 \to 5, 5→35 \to 3. The vertices 1,21, 2 reach each other; 3,4,53, 4, 5 form a cycle; 2→32 \to 3 goes from the first group to the second but nothing comes back. Two components, {1,2}\{1, 2\} and {3,4,5}\{3, 4, 5\}. A DAG with nn vertices has nn components (every vertex alone); a strongly connected graph has 11.

EX 5Typical statements

GATE level

(a) A directed graph is acyclic iff DFS finds no back edge: true. (b) In a DFS of an undirected graph there can be a cross edge: false. (c) In a DAG, for every edge u→vu \to v, f[u]>f[v]f[u] > f[v]: true. (d) A DAG has a unique topological order: false in general (unique only if there is an edge between each pair of consecutive vertices). (e) The time of topological sorting with adjacency lists: Θ(V+E)\Theta(V + E). (f) Which traversal order of vertices gives the topological order? Reverse of the order in which they finish (reverse postorder). (g) Maximum number of edges of a DAG on nn vertices: n(n−1)/2n(n-1)/2 (a total order, one edge for every pair).

Cheat box

Cheat box

  • Edge u→vu \to v during DFS: vv white →\to tree; gray →\to back; black with d[u]<d[v]→d[u] < d[v] \to forward; black with d[v]<d[u]→d[v] < d[u] \to cross.
  • Undirected: only tree and back edges. Directed: cycle   ⟺  \iff back edge.
  • DAG: f[u]>f[v]f[u] > f[v] for every edge u→vu \to v. Topological order = decreasing finish time (or Kahn with in-degrees). Θ(V+E)\Theta(V + E). Unique iff a Hamiltonian path of consecutive edges.
  • Kahn: stops early (with vertices left) iff a cycle exists.
  • SCC (Kosaraju): DFS on GG; reverse the edges; DFS in decreasing finish time; each tree is a component. Θ(V+E)\Theta(V + E). Components come out in topological order of the component graph; the component graph is a DAG.
  • A DAG with nn vertices: at most n(n−1)/2n(n-1)/2 edges, nn components.

Traps and GATE patterns

Connections

All of this is DFS (BFS and DFS) with the colour rule. The reachability relation computed here for strong connectivity is the transitive closure that Floyd-Warshall computes for all pairs; the graphs are represented as in graph representations.

PYQs

10 previous year questions from your book. I re-solved each one myself (9 by running or simulating, 1 by reasoning only); the book's key is shown next to my answer. All PYQs

GATE 2026 · Set 2 · MCQ · 2 marksQ3 · page 113 of the book
Let G be a weighted directed acyclic graph with m
edges and n vertices. Given G and a source vertex s
in G, which one of the following options gives the
worst case time complexity of the fastest algorithm
to find the lengths of shortest paths from s to all
vertices that are reachable from s in G?
  • (a)Θ(m + n)
  • (b)Θ(m + n log(n))
  • (c)Θ(nm)
  • (d)Θ(n3)
GATE 2026 · Set 1 · MSQ · 2 marksQ1 · page 136 of the book
Consider the following pseudocode for depth-first
search (DFS) algorithm which takes a directed
graph G(V,E) as input, where d[v] and f[v] are the
discovery time and finishing time, respectively, of
the vertex v ∈V.

DFS(G) :
unmark all v ∈ V
t ← 0
for each v ∈ V
if v is unmarked
t ← Explore
(G, v, t )
end if
end for
Explore ( G, v, t ):
mark v
t ← t + 1
d[v] ← t
for each (v, w) ∈ E
if w is unmarked
t ← Explore (G, w, t)
end if
end for
t ← t + 1
f[v] ← t
return t
Suppose that the input directed graph G(V,E) is a
directed acyclic graph (DAG). For an edge
(u,v)∈E, which of the following options will
NEVER be correct?
  • (a)d[u]<d[v]<f[v]<f[u]
  • (b)d[v]<d[u]<f[u]<f[v]
  • (c)d[v]<f[v]<d[u]<f[u]
  • (d)d[u]<d[v]<f[u]<f[v]
GATE 2025 · Set 2 · MSQ · 1 markQ4 · page 137 of the book
Which of the following statements regarding
Breadth First Search (BFS) and Depth First Search
(DFS) on an undirected simple graph G is/are
TRUE?
  • (a)A DFS tree of G is a Shortest Path tree of G.
  • (b)Every non-tree edge of G with respect to a DFS tree is a forward/back edge.
  • (c)If (u, v) is a non-tree edge of G with respect to a BFS tree, then the distances from the source vertex s to u and v in the BFS tree are within ±1 of each other.
  • (d)Both BFS and DFS can be used to find the connected components of G.
GATE 2024 · Set 1 · MCQQ5 · page 137 of the book
Let G be a directed graph and T a depth first search
(DFS) spanning tree in G that is rooted at a vertex
GATE 2018 · MCQ · 2 marksQ9 · page 137 of the book
Match Let G be a simple undirected graph. Let TD be
a depth first search tree of G. Let TB be a breadth
first search tree of G. Consider the following
statements.
(I) No edge of G is a cross edge with respect to TD.
(A cross edge in G is between two nodes neither of
which is an ancestor of the other in TD.)
(II) For every edge (u,v) of G, if u is at depth i and v
is at depth j in TB, then |i - j| = 1.
Which of the statements above must necessarily be
true?
  • (a)I only
  • (b)II only
  • (c)Both I and II
  • (d)Neither I nor II ALGORITHMS Check Out Our Gate Courses & Secure Your Dream Rank !
GATE 2007 · MCQ · 1 markQ15 · page 138 of the book
A depth-first search is performed on a directed
acyclic graph. Let d[u] denote the time at which
vertex u is visited for the first time and f[u] the time
at which the DFS call to the vertex u terminates.
Which of the following statements is always TRUE
for all edges (u, v) in the graph ?
  • (a)d[u] < d[v]
  • (b)d[u] < f[v]
  • (c)f[u] < f[v]
  • (d)f[u] > f[v] ALGORITHMS Check Out Our Gate Courses & Secure Your Dream Rank !
GATE 2007 · MCQ · 1 markQ16 · page 139 of the book
Consider the DAG with V = {1,2,3,4,5,6}, shown
below

Which of the following is NOT a topological
ordering?
  • (a)1 2 3 4 5 6
  • (b)1 3 2 4 5 6
  • (c)1 3 2 4 6 5
  • (d)3 2 4 1 6 5
GATE 2006 · MCQQ17 · page 139 of the book
Consider the depth-first-search of an undirected
graph with 3 vertices P, Q, and R. Let discovery
time d(u) represent the time instant when the
vertex u is first visited, and finish time f(u)
represent the time instant when the vertex u is last
visited. Given that
d(P)=5 units f(P)=12 units
d(Q)=6 units f(Q)=10 units
d(R)=14 unitf(R)=18 units
Which one of the following statements is TRUE
about the graph?
  • (a)There is only one connected component
  • (b)There are two connected components, and P and R are connected
  • (c)There are two connected components, and Q and R are connected
  • (d)There are two connected components, and P and Q are connected
GATE 2006 · MCQ · 1 markQ18 · page 139 of the book
Let T be a depth first search tree in a undirected
graph G. Vertices u and v are leaves of this tree T.
The degrees of both u and v in G are at least 2.
Which one of the following statements is true?
  • (a)There must exist a vertex w adjacent to both u and v in G
  • (b)There must exist a vertex w whose removal disconnects u and v in G
  • (c)There must be exist a cycle in G containing u and v
  • (d)There must exist a cycle in G containing u and all its neighbours in G
GATE 2021 · Set 1 · MCQQ8 · page 67 of the book
An articulation point in a connected graph is a
vertex such that removing the vertex and its
incident edges disconnects the graph into two or
more connected components. Let T be a DFS three

Self-check

Question 1

In a DFS of a directed graph, the edge u→vu \to v reaches a gray vertex. What kind is it and what does it show?

Show answer

A back edge; the graph has a directed cycle.

Question 2

Give a topological order of the DAG with edges 1→21 \to 2, 1→31 \to 3, 3→23 \to 2, 2→42 \to 4.

Show answer

1,3,2,41, 3, 2, 4 (the only one: 11 before 33 before 22 before 44).

Question 3

Why does Kosaraju's second search use the reversed graph?

Show answer

The vertex with the largest finish time lies in a source component of GG, which is a sink in GTG^T: a search in GTG^T from it stays inside its own component.

Question 4

How many strongly connected components does a DAG with 55 vertices have?

Show answer

55: every vertex is its own component.

Revision card

One-screen revision

  • Edge kinds by colour of vv: white tree, gray back, black forward (d[u]<d[v]d[u] < d[v]) or cross.
  • Directed cycle   ⟺  \iff back edge. Undirected: no cross edges.
  • Topological order: decreasing finish time or Kahn; DAGs only; Θ(V+E)\Theta(V + E); unique iff consecutive edges.
  • SCC: DFS, reverse graph, DFS in decreasing finish; component graph is a DAG.

References

  • ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (3rd edition), Chapter 22 (22.3 properties of depth-first search, 22.4 topological sort, 22.5 strongly connected components)
  • ·Sedgewick and Wayne, Algorithms (4th edition), Section 4.2 Directed Graphs
  • ·Dasgupta, Papadimitriou, Vazirani, Algorithms, Sections 3.2 to 3.4 (depth-first search in directed graphs, strongly connected components)

Verification

On 1000 random graphs (500 undirected, 500 directed) the edge kinds decided by the colour rule were compared with the kinds decided from the discovery and finish intervals; undirected graphs had no cross edges; a directed graph had a back edge exactly when a reachability test found a cycle. Topological orders: reversed finish order and Kahn's order were valid on 400 random DAGs and found among all valid permutations, every DAG search had no back edge, the number 75 of orders of the page DAG was found by trying all 8! permutations, and the claim that the order is unique exactly when consecutive vertices are joined by edges was checked on 300 random DAGs. Kosaraju's components were compared with mutual reachability on 500 random digraphs and the components were found in topological order of the component graph. The animation and the three tables are real runs of the C code on the page. Textbook chapter references are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (loop counts, recurrences, merge and quicksort counts and averages, hash probes and load-factor formulas, DP tables, MST and shortest-path runs, Floyd matrices); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.

last verified: never