Graph Representations & Traversals (BFS/DFS)

Graph — উপস্থাপনা ও traversal

Read: ~45 min Advanced 8 practice problems Live code runner

1. Graphs Are Everywhere

A graph G = (V, E) is a set of vertices and edges. Roads, social networks, web links, dependency graphs, the Internet, even chess positions — all are graphs. Almost every Computer Science problem reduces to a graph in disguise.

ঢাকা শহরের রাস্তা, Facebook-এ বন্ধু সম্পর্ক, Wikipedia-র link structure, একটি project-এর dependency tree — সব graph। DSA-এর বাকি অর্ধেক graph নিয়েই।

2. Three Common Representations

RepresentationMemoryEdge queryList neighboursBest for
Adjacency matrix m[u][v]O(V²)O(1)O(V)Dense graphs, small V
Adjacency list vector<int> adj[V]O(V + E)O(deg(u))O(deg(u))Sparse graphs, almost everything
Edge listO(E)O(E)O(E)Kruskal MST, Bellman-Ford
ICPC-তে প্রায় সব সময় adjacency list। V ছোট ও E ঘন হলে matrix। Kruskal-এর জন্য edge list।

3. BFS — Layer by Layer

Breadth-first search uses a queue. Mark source as visited, push, then repeatedly pop u and push every unvisited neighbour. Each vertex enters the queue once → O(V + E). BFS computes the shortest path in unweighted graphs.

bfs.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    int V = 6;
    vector<vector<int>> adj(V);
    vector<pair<int,int>> edges = {{0,1},{0,2},{1,3},{2,3},{3,4},{4,5}};
    for (auto [u, v] : edges) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    vector<int> dist(V, -1);
    queue<int> q;
    dist[0] = 0; q.push(0);
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int v : adj[u]) if (dist[v] == -1) {
            dist[v] = dist[u] + 1;
            q.push(v);
        }
    }
    for (int i = 0; i < V; i++)
        cout << "dist[0..." << i << "] = " << dist[i] << "\n";
}

4. DFS — Go Deep First

Depth-first search uses a stack (or recursion). Useful for cycle detection, topological sort, articulation points, SCC, and traversal-order tasks. Like BFS, O(V + E).

dfs.cpp
#include <bits/stdc++.h>
using namespace std;

vector<vector<int>> adj;
vector<bool> vis;

void dfs(int u) {
    vis[u] = true;
    cout << u << " ";
    for (int v : adj[u]) if (!vis[v]) dfs(v);
}

int main() {
    int V = 6;
    adj.assign(V, {}); vis.assign(V, false);
    vector<pair<int,int>> edges = {{0,1},{0,2},{1,3},{2,3},{3,4},{4,5}};
    for (auto [u, v] : edges) { adj[u].push_back(v); adj[v].push_back(u); }
    dfs(0);
}
Recursion depth caution On chains of 10⁵+ vertices, recursive DFS may overflow the stack. Convert to iterative DFS with an explicit std::stack for very deep graphs.

5. Cycle Detection

  • Undirected graph: during DFS, if you see a visited neighbour that is not your parent, there is a cycle.
  • Directed graph: use 3 colours — WHITE (unvisited), GRAY (in current DFS path), BLACK (finished). Seeing GRAY → cycle.
  • BFS in DAG: Kahn's algorithm — if you can't pop V vertices, a cycle exists.
Undirected — DFS-এ visited neighbour যদি parent না হয় তবে cycle। Directed — 3-colour DFS, GRAY দেখলেই cycle।

6. Practice Problems

  1. Number of islands in a 0/1 grid using DFS or BFS.
    0/1 grid-এ islands গুনুন।
    ✨ Show Answer (উত্তর দেখুন)
    a1.cpp
    #include <bits/stdc++.h>
    using namespace std;
    vector<string> g;
    int R, C;
    void dfs(int i, int j) {
        if (i<0||j<0||i>=R||j>=C||g[i][j]=='0') return;
        g[i][j] = '0';
        dfs(i+1,j); dfs(i-1,j); dfs(i,j+1); dfs(i,j-1);
    }
    int main() {
        g = {"11000","11000","00100","00011"};
        R = g.size(); C = g[0].size();
        int cnt = 0;
        for (int i=0; i<R; i++) for (int j=0; j<C; j++)
            if (g[i][j] == '1') { cnt++; dfs(i,j); }
        cout << cnt;
    }
  2. Detect cycle in an undirected graph.
    Undirected graph-এ cycle।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: DFS with parent tracking. If during DFS at u, you see neighbour v that is visited and v ≠ parent[u], cycle exists. Run from every component.

  3. Detect cycle in a directed graph (3-colour DFS).
    Directed graph-এ cycle — 3-colour DFS।
    ✨ Show Answer (উত্তর দেখুন)
    a3.cpp
    #include <bits/stdc++.h>
    using namespace std;
    vector<vector<int>> adj;
    vector<int> col; // 0 white, 1 gray, 2 black
    bool cyc(int u) {
        col[u] = 1;
        for (int v : adj[u]) {
            if (col[v] == 1) return true;
            if (col[v] == 0 && cyc(v)) return true;
        }
        col[u] = 2;
        return false;
    }
    int main() {
        adj = {{1},{2},{0},{2}}; col.assign(4, 0);
        bool hasCycle = false;
        for (int i = 0; i < 4; i++)
            if (col[i] == 0 && cyc(i)) hasCycle = true;
        cout << (hasCycle ? "YES" : "NO");
    }
  4. Bipartite check via BFS 2-colouring.
    Bipartite যাচাই — BFS 2-colouring।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: BFS, alternating colours. If you ever reach a neighbour with the same colour as yourself, it is not bipartite. O(V + E).

  5. Word Ladder — shortest transformation from begin to end where each step changes one letter and is in the dictionary.
    Word Ladder — BFS দিয়ে shortest transformation।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: BFS where neighbours of a word are all dictionary words at Hamming distance 1. Use intermediate "wildcard" buckets (like "h*t") for O(L · 26) neighbour generation per word.

  6. Number of connected components in an undirected graph.
    Undirected graph-এ connected components।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: for each unvisited vertex, run BFS/DFS and count one. Or use DSU (Module 22).

  7. Flood fill of a 2D image at coordinate (sr, sc) with color newColor.
    Flood fill — DFS।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: DFS from (sr, sc), only spreading to cells with the original colour. Replace with newColour as you visit.

  8. Shortest path in an unweighted grid (BFS) from top-left to bottom-right.
    Unweighted grid-এ shortest path — BFS।
    ✨ Show Answer (উত্তর দেখুন)

    Approach: standard BFS on a grid with 4-directional moves. dist[r][c] = dist[parent] + 1.

Summary — Module 26

Adjacency list is the default representation. BFS finds shortest paths in unweighted graphs in O(V+E). DFS powers cycle detection, topological sort, SCC, articulation points. Cycle detection differs for undirected (parent check) and directed (3-colour). Phase 6 begins.

BFS unweighted shortest path-এর জন্য, DFS recursion-friendly যেকোনো task-এর জন্য। Phase 6 শুরু — পরের module-এ topo sort + Dijkstra।

Next Module → Topological Sort & Shortest Paths I — Dijkstra-এর জগতে।