Skip to main content

Graph

Learning Roadmap

Solid arrows are prerequisites - master the source before the target. Dashed nodes are the stretch tier, worth visiting once the core is solid.

Learn

  • Graph Anatomy - the vocabulary, drawn out: vertices, edges, adjacency vs incidence, degree and the handshake lemma, walks/trails/paths/cycles, simple vs multigraphs, dense vs sparse, and the shape zoo. Start here if any graph word has ever been fuzzy.
  • Representation - graph properties, adjacency list/matrix/edge list, building the graph from the input you were given, and the traps that come from mixing representations up. After this: you can pick the right representation and read matrix rows without the index-vs-value bug.
  • Traversal - the one BFS/DFS engine, its classic traps, and connected components. This is the page to actually internalize - almost every graph problem is this engine with one knob turned.
  • Cycles & Ordering - cycle detection (directed and undirected), topological sort, union-find. Builds directly on Traversal's DFS.
  • Shortest Paths & Bipartite Check - Dijkstra, Bellman-Ford, and 2-coloring via BFS. What BFS becomes once edges stop costing the same.
  • MST, SCC & Connectivity - Kruskal, Prim, Tarjan, Kosaraju, bridges, articulation points, condensation. Everything about a graph's connective structure: cheapest way to connect it, which vertices can all reach each other, and which single edge or vertex would break it.
  • Eulerian & Hamiltonian - every-edge-once vs every-vertex-once, degree conditions, Hierholzer, and why one is linear and the other NP-complete. Read it for the asymmetry alone.
  • Coloring & Covering - the chromatic number, greedy coloring, independent sets, cliques, vertex covers, and the NP-hard map. Where the cliff between 2 colors and 3 colors actually is.
  • Flows & Matching - max flow, min cut, bipartite matching, Konig and Hall, and the reduction table. The polynomial half of the hard problems - read section 4 even if you skip the rest.
  • Grids as Graphs - the implicit edges of a 2D grid, DIRS4 vs DIRS8, the four ways to track visited, flood fill, the border-seeded inversion, and layered grids. The most common graph problem is the one that never says "graph".
  • Trees as Graphs - a tree given as an edge list: rooting it, diameter by double sweep, center vs centroid, LCA by binary lifting, tree DP and rerooting. What to do when there is no .left and .right.
  • Graphs in the Wild - which production system runs which algorithm, centrality and PageRank, what changes when the graph does not fit in memory, and graph databases. Not needed for interviews; read it to make the rest stick.

What do I reach for

The whole section compressed into one lookup. Read the question, not the graph: the phrasing decides the algorithm far more often than the input shape does.

The question asks forReach forCost
"is there a path", "are these connected", "how many groups"DFS or BFS, or union-find if edges arrive one at a timeO(V + E)
"fewest steps", "minimum moves", unweightedBFS - TraversalO(V + E)
"distance to the nearest of several starts"multi-source BFS - seed every source at distance 0O(V + E)
"cheapest route", non-negative weightsDijkstra - Shortest PathsO((V + E) log V)
"cheapest route", some weight is negativeBellman-Ford, and it detects negative cycles tooO(V * E)
"cheapest route between every pair"Floyd-Warshall, if V is small or the graph is denseO(V^3)
"is this schedulable", "what order", "does it deadlock"topological sort - Cycles & OrderingO(V + E)
"how many rounds/semesters/stages"Kahn's, drained one generation at a timeO(V + E)
"cheapest way to connect everything"Kruskal or Prim - MSTO(E log E)
"which groups can all reach each other"Tarjan or Kosaraju, then condense to a DAGO(V + E)
"which single link/machine is critical"bridges and articulation points - low-linkO(V + E)
"split into two groups with no conflict inside"2-coloring BFS - bipartite checkO(V + E)
"use every edge exactly once"degree parity, then Hierholzer - EulerianO(V + E)
"visit every vertex exactly once", n <= 20bitmask DP - HamiltonianO(2^n * n^2)
"assign each of these to one of those"bipartite matching - Flows & Matchingpolynomial
"what is the bottleneck", "cheapest set of links to cut"max flow / min cutpolynomial
"largest conflict-free set", "fewest to cover everything"independent set / vertex cover - NP-hard unless bipartite, a tree, or n is small (Coloring & Covering)see the NP-hard map
it is a grid and asks about regions, distances, or reachabilityBFS or DFS with a direction-offset neighbour function - Grids as GraphsO(R * C)
it is a tree (edge list, n - 1 edges) and asks for the longest pathdouble-sweep BFS for the diameter - Trees as GraphsO(V)
"which root minimises the height", "the middle of the tree"peel leaves layer by layer to find the centerO(V)
repeated "distance between these two tree vertices"LCA by binary liftingO(V log V) prep, O(log V) per query
the answer for every vertex as rootrerooting: one down pass, one up passO(V)
"cheapest subject to at most k X"state-augmented Dijkstra over (node, k) - Dijkstra variantsO(E k log(V k))
"minimise the largest single step"Dijkstra with max relaxation, or binary search + BFSO((V + E) log V)
pick true/false per variable, constraints over pairs2-SAT via the implication graph and SCCs - 2-SATO(V + E)
tasks with durations: "how long, and which tasks are tight"critical path method - forward pass, backward pass, slackO(V + E)
"which of these is most important/influential"centrality or PageRank - Graphs in the Wildvaries

The bug checklist

Every trap on the learn pages, compressed into the order they tend to bite. If a graph solution is wrong and you do not know why, read down this list.

#CheckSymptom when wrong
1Did you append both directions for an undirected edge?Components over-counted; paths reported missing.
2Does [a, b] point the way you think? For prerequisites the edge runs b -> a.Order comes out reversed. Note the boolean version of the problem still passes.
3Are isolated vertices in the adjacency structure, or did you build only from edges?Component count too low; len(adj) != n.
4Is visited marked on enqueue/push, not on dequeue/pop?Duplicates flood the queue; recursive DFS overflows.
5Does the visited key include every part of the state - (r, c, keys), (node, stops)?A valid route is rejected; answer too high or -1.
6Is the outer for v in graph: if v not in visited loop present?Only one component is ever processed.
7Directed cycle detection: 3 colours and no parent-skip. Undirected: parent-skip is required.False negatives on 2-cycles, or false positives on a plain DAG.
8Bounds checked before indexing a grid cell?Python negative indexing wraps silently - no error, wrong answer.
9Kahn: is the cycle test len(order) == n, not "the pool started empty"?Cycles that leave the pool non-empty at the start are missed.
10Postorder built and then reversed? (topological sort, Hierholzer, Kosaraju)The answer is exactly backwards.
11Dijkstra: is every weight non-negative? Prim: is the heap key the raw edge weight, not a running total?Silently wrong optimum; Prim builds a shortest-path tree instead of an MST.
12Floyd-Warshall: is k the outermost loop?Distances too large; passes on small inputs.
13Bridges use low[v] > disc[u]; articulation points use >= plus the root rule.Correct on trees, wrong on everything with a cycle.
14Union-find: size[winner] += size[loser], and compression writes to the caller's entry.Off-by-a-few sizes; compression silently does nothing.
15Was parent[v] = u set inside the same if as the distance update?Correct distances, nonsense reconstructed path.
16Recursion depth: could this input exceed about 1000 frames?RecursionError on large but legal input.

Practice