A DSA + Interview + CP focused Graph Roadmap with process, intuition, and approach for every topic. Best for OA + Interviews + Competitive Programming.
Process:
- Understand nodes = vertices
- Understand connections = edges
- Directed → one-way edge
- Undirected → two-way edge
Approach:
- Convert real problems into nodes + relationships
- Think in terms of network traversal
Process:
- Store neighbors of each node
- Choose list for sparse graph
- Choose matrix for dense graph
Approach:
- Adjacency List → O(V+E) space efficient
- Matrix → O(V²) fast edge check
Process:
- Count edges entering node
- Count edges leaving node
Approach:
- Important for topological sort
- Useful in Kahn’s BFS
Process:
- Start from source
- Use queue
- Visit level by level
Approach Pattern:
- Push source in queue
- Mark visited
- Pop node
- Push all unvisited neighbors
Best For: shortest path in unweighted graph
Process:
- Go as deep as possible
- Backtrack when stuck
Approach:
- Recursive DFS
- Stack-based DFS
- Great for components and cycles
Process:
- Loop over all nodes
- Start BFS/DFS from unvisited nodes
Approach:
- Every fresh DFS = new component
Process:
- Nodes = total vertices
- Sum adjacency list sizes
Approach:
- Undirected: edges = sum/2
- Directed: direct sum
Process:
- Run DFS from any node
- Count visited nodes
Approach:
- If visited == total nodes → connected
Process:
- Run DFS from each unvisited node
- Count DFS calls
Approach:
- DFS call count = components
Process:
- Treat cell as node
- Explore 4 directions
Approach:
- BFS/DFS on matrix
- Boundary checks mandatory
Process:
- Scan grid
- Start DFS on every unvisited land
Approach:
- Every DFS = one island
Process:
- DFS with parent tracking
- If visited neighbor != parent → cycle
Approach:
- BFS pair(node,parent)
- DFS recursion with parent
Process:
- Use visited + pathVisited
Approach:
- Back edge in recursion stack = cycle
Process:
- DAG ordering problem
Approach:
- DFS + stack
- BFS using indegree
Process:
- 2-color graph
- Adjacent nodes different color
Approach:
- BFS/DFS coloring
- Same color conflict = not bipartite
Process:
- BFS from source
- Level = distance
Approach:
- distance[child] = distance[node]+1
Process:
- Pick minimum distance node
- Relax edges
Approach:
- Min heap + distance array
- Works for positive weights
Process:
- Relax all edges V-1 times
Approach:
- Good for negative edges
Process:
- Run 1 extra relaxation
Approach:
- If still relaxes → negative cycle
Process:
- Push all sources initially
Approach:
- All start at distance 0
- Expand simultaneously
Process:
- BFS over matrix
- Distance per cell
Approach:
- Use queue + direction arrays
Process:
- Multi-source BFS from rotten oranges
Approach:
- Each level = 1 minute
Approach:
- DFS on adjacency matrix
- Count components
Process:
- Each word = node
- One letter difference = edge
Approach:
- BFS with dictionary set
Approach:
- DFS/BFS + hashmap old→new node
Approach:
- DAG cycle + topological sort
Process:
- Try every node as intermediate
Approach:
- Triple loop DP
- All-pairs shortest path
Goal: minimum total edge weight connecting all nodes
Approach:
- Sort edges
- Use DSU
- Pick smallest safe edge
Approach:
- Grow MST from source
- Min heap edges
Process:
- Find parent
- Union sets
Approach:
- Path compression
- Union by size/rank
Process:
- DFS order
- Reverse graph
- DFS by stack order
Approach:
- Low-link + discovery time
- Finds SCC / bridges / articulation
Condition:
- low[child] > tin[parent]
Condition:
- low[child] >= tin[node]
Approach:
- Topological order + relax edges
Approach:
- Deque
- Weight 0 → push front
- Weight 1 → push back
Approach:
- Modified Dijkstra
- Store multiple distances
Approach:
- Dijkstra standard application
Approach:
- Hierholzer DFS + lexical order
Approach:
- Sparse parent table
- Fast kth ancestor / LCA
Approach:
- Break tree into heavy chains
- Segment tree over chains
Approach:
- Flatten tree into array
- Subtree becomes range
Approach:
- Recursively split tree by centroid
Approach:
- Versioned DSU states
Approach:
- Offline queries + DSU rollback
Approach:
- Augmenting paths
- Residual graph
Approach:
- BFS level graph
- DFS blocking flow
Approach:
- Use max-flow min-cut theorem
Approach:
- DFS augmenting path / Hopcroft-Karp
Approach:
- Assignment optimization
Approach:
- DP + bitmask
- state = mask, node
Approach:
- Split state space in half
Approach:
- Backtracking / greedy / DP bitmask
Graph Basics
→ BFS + DFS
→ Grid Problems
→ Cycle + Topological Sort
→ Shortest Path
→ MST + DSU
→ SCC + Bridges
→ Tree Algorithms
→ Flow + Matching
→ Advanced CP Graphs
For interviews:
- BFS
- DFS
- Topological sort
- Dijkstra
- DSU
- MST
- SCC
- Bridges
For CP:
- HLD
- Binary lifting
- Max flow
- Matching
- TSP DP
After completing this README roadmap, you can solve:
- 90% Interview Graph Problems
- Most OA graph questions
- Advanced Codeforces/LeetCode Hard graph problems
This section explains the math intuition / proof logic behind the algorithms so you can solve problems by reasoning, not memorization.
- Works on levels (distance layers)
- If source is at distance
0, then all direct neighbors are at1 - Their neighbors are at
2 - Hence BFS guarantees:
dist[v] = minimum number of edges from source - This is why BFS solves shortest path in unweighted graphs.
- DFS explores one full path before trying another.
- This naturally creates a tree of recursion states.
- The math idea is:
Every edge is explored once - Total complexity:
O(V + E)
DFS is based on recursive graph decomposition.
A graph is partitioned into disjoint reachable sets.
Mathematically:
-
If
ucan reachv, both belong to same component. -
Components form an equivalence relation:
- reflexive
- symmetric (for undirected)
- transitive
So:
Number of fresh DFS/BFS starts = number of components
A cycle exists if:
- we revisit a visited node
- and it is not the parent
Mathematical condition:
visited[child] = true && child != parent
A cycle exists if there is a back edge.
Condition:
visited[v] && pathVisited[v]
This means current recursion path loops.
For every directed edge:
u -> v
The ordering must satisfy:
u appears before v
This is a partial order problem.
Kahn’s Algorithm math:
- indegree = number of prerequisites
- node with indegree 0 can be solved first
This is why it solves Course Schedule.
A graph is bipartite if it can be divided into 2 disjoint color sets.
Mathematical property:
- No odd length cycle
- Equivalent theorem:
Graph is bipartite iff no odd cycle exists
Color relation:
color[child] = 1 - color[node]
Core equation:
dist[v] = min(dist[v], dist[u] + wt)
This is called edge relaxation.
Why greedy works:
- smallest unvisited distance is always final
- only valid for non-negative weights
This follows greedy proof by contradiction.
Shortest path can contain at most:
V-1 edges
So we relax all edges exactly V-1 times.
Negative cycle theorem:
- If relaxation happens on
Vthiteration - shortest path is unbounded
- therefore negative cycle exists
DP relation:
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
Meaning:
- shortest path from
itoj - either direct
- or through node
k
This is all-pairs shortest path DP.
For MST:
- total nodes =
V - total selected edges =
V-1
Mathematical theorem:
Choose the minimum safe edge crossing a cut.
This is the cut property.
Used by:
- Kruskal
- Prim
Each component behaves like a disjoint mathematical set.
Operations:
find(x)→ representative elementunion(a,b)→ merge two sets
Optimization proof:
- path compression + union by rank
- amortized nearly constant
O(alpha(n))
Edge (u,v) is bridge if removing it increases components.
Condition:
low[v] > tin[u]
Meaning:
- child subtree cannot reach ancestor of parent
- so edge is critical
Node u is articulation point if removing it disconnects graph.
Condition:
low[v] >= tin[u]
Meaning:
- child subtree depends fully on
u
Weights are only 0 or 1.
Math idea:
- weight
0→ same distance layer - weight
1→ next layer
So deque simulates Dijkstra in:
O(V + E)
Parent jump table:
up[node][j] = 2^j th ancestor
Mathematical decomposition:
Any integer k can be written as powers of 2.
Example:
13 = 8 + 4 + 1
So kth ancestor becomes binary jumps.
Core theorem:
Flow in = Flow out
Conservation law:
sum(incoming) = sum(outgoing)
Residual capacity:
residual = capacity - flow
Final theorem:
Max Flow = Min Cut
This is the base of Dinic and Edmonds-Karp.
For every graph problem ask:
- Is it reachability? → BFS/DFS
- Is it ordering? → Topological
- Minimum cost? → Dijkstra/MST
- Components merging? → DSU
- Critical edge/node? → Bridges/AP
- Tree queries? → Binary lifting/HLD
- Capacity transfer? → Flow
This is the real mathematical decision tree for graph problems.