Graphs
Graph problems are mostly about (1) modeling correctly and (2) picking the right tool for the constraints.
A good workflow:
- Model the problem as a graph.
- What are the nodes?
- What are the edges?
- Directed or undirected?
- Weighted or unweighted?
- Estimate constraints.
- Let
nbe the number of nodes andmthe number of edges. - Use an adjacency list unless the graph is very dense.
- Typical targets:
O(n+m),O(m log n), orO(n^2)depending on constraints.
- Let
1. Modeling Patterns
Before algorithms, make sure you’re building the right graph.
Common modeling patterns
- Grid → graph: each cell is a node; edges go to neighbors (4-dir / 8-dir); walls block edges.
- State graph (BFS / shortest path on states): node =
(position, extra_state)such as(v, mask)or(v, parity). - Constraints → directed edges: “A must come before B” becomes an edge
A -> B. - Equivalence / grouping: “in the same component” often points to DSU / BFS / DFS.
Sanity checks
- Directed vs undirected?
- Weighted vs unweighted?
- Is
mlarge (up to2e5)? AvoidO(n^2)methods. - Are there negative weights? Dijkstra may not apply.
2. Depth-First Search (DFS)
Depth-First Search explores “as deep as possible” before backtracking.
![]()
When to use / common patterns
- Finding connected components (undirected)
- Reachability / flood fill (including grids)
- Detecting cycles (undirected): look for a back-edge to a visited node that isn’t the parent
- Building DFS orderings (e.g., SCC, or topo via DFS finish times)
Implementation Notes
- Visited array prevents revisits.
- Parent tracking helps reconstruct paths / build a DFS tree.
- DFS tree fact (undirected graphs): DFS defines a rooted DFS tree (or forest). Every edge is either a tree edge or a back edge that connects a node to one of its ancestors. In particular, there are no “cross edges” between different DFS subtrees in an undirected DFS.
- Watch out for recursion depth (especially in Python). Use an explicit stack if needed.
- If you just need reachability (either DFS or BFS works), DFS is often the quickest to code.
Complexity
O(n + m)time,O(n)memory
Example problems:
3. Breadth-First Search (BFS)
Breadth-First Search explores in increasing distance from a start node (by “levels”).

When to use
- Shortest path in unweighted graphs (each edge cost = 1)
- Finding minimum number of moves on grids
- Multi-source shortest distances (start from many sources at once)
- Layering / level-by-level processing
Implementation Notes
- Queue + dist array: in an unweighted graph, the first time you visit a node you’ve found its shortest distance.
- Parent array: reconstruct the shortest path.
Complexity
O(n + m)time,O(n)memory
Example problems:
More practice for DFS and BFS:
- Building Teams (CSES)
- Subarray Sum Constraints (CSES)
- Palindromic Paths (CF)
- Third Avenue (AC)
- Olya and Energy Drinks (CF)
4. Shortest Paths
“Shortest path” depends heavily on edge weights.
Choosing the right tool
- Unweighted: BFS
- Non-negative weights: Dijkstra (min-heap /
priority_queue) - Negative weights (no negative cycles): Bellman–Ford
- All-pairs, small
n(~500): Floyd–Warshall
Dijkstra (most common) Works when all edge weights are >= 0.
- Maintain
dist[v]= best known distance - Use a min-heap priority queue on
(dist, node) - Ignore stale heap entries (classic CP trick)
Complexity
- Dijkstra:
O(m log n)(often written asO(m log m)in implementations usingpush-heavy heaps) - Bellman–Ford:
O(nm) - Floyd–Warshall:
O(n^3)
Example problems:
- Shortest Routes I (CSES) (check your Dijkstra implementation)
- Shortest Routes II (CSES) (check your Floyd–Warshall implementation)
- Shortest Routes III (CSES) (check your Bellman–Ford implementation)
Practice:
5. Topological Sort
Topological sort orders vertices of a directed acyclic graph (DAG) such that for every edge u -> v, u appears before v.
When to use
- Dependencies / prerequisites
- Scheduling with ordering constraints
- Any problem that forms a DAG and asks for an order or DP over dependencies
Key properties
- Only possible for DAGs (no directed cycles)
- Multiple valid orderings may exist
- Two standard methods:
- Kahn’s algorithm (BFS-based): indegree + queue
- DFS finish times: reverse postorder
Cycle detection
- Kahn: if you can’t process all nodes, there is a cycle.
- DFS: recursion-stack technique.
Complexity
O(n + m)
Example problems:
- Course Schedule (CSES)
- Commuter Pass (JOI) solution may be found on USACO Guide.