Back to DSA & Algorithms
DSA & Algorithms
medium
mid

How do you approach graph based optimization problems in interviews?

Catch-all category. Common forms: shortest path (BFS for unweighted, Dijkstra for weighted, Bellman-Ford for negative edges, A* with heuristic), minimum spanning tree (Kruskal/Prim), max-flow/min-cut (Ford-Fulkerson), strongly connected components (Tarjan/Kosaraju), topological sort (DFS or Kahn). Recognize the problem shape, then pick the algorithm.

5 min read·~25 min to think through

"Graph optimization" is a category, not a single problem. Interviewers want to see you recognize the problem shape and pick the right algorithm.

Recognize the shape

ShapeAlgorithm
Shortest path, unweightedBFS
Shortest path, weighted, non-negativeDijkstra (priority queue)
Shortest path, can have negative edgesBellman-Ford
Shortest path with heuristic (e.g., grid + Manhattan)A*
All-pairs shortest pathsFloyd-Warshall (dense) or N × Dijkstra (sparse)
MST (cheapest connecting tree)Kruskal (with union-find) or Prim
Max flow / Min cutFord-Fulkerson / Edmonds-Karp
Topological order (DAG)Kahn's (BFS) or DFS post-order
Strongly connected componentsTarjan or Kosaraju
Detect cycleDFS with colors / union-find
Bipartite checkBFS / DFS 2-coloring
Articulation points / bridgesTarjan
Connected componentsBFS / DFS / union-find

Shortest path (most common)

BFS — unweighted

js
function bfsShortest(graph, start, target) {
  const queue = [[start, 0]];
  const visited = new Set([start]);
  while (queue.length) {
    const [node, dist] = queue.shift();
    if (node === target) return dist;
    for (const n of graph[node]) {
      if (!visited.has(n)) { visited.add(n); queue.push([n, dist + 1]); }
    }
  }
  return -1;
}

Dijkstra — weighted, non-negative

js
function dijkstra(graph, start) {
  const dist = new Map([[start, 0]]);
  const pq = new MinHeap([[0, start]]);   // [distance, node]
  while (pq.size) {
    const [d, node] = pq.pop();
    if (d > (dist.get(node) ?? Infinity)) continue;
    for (const [n, w] of graph[node]) {
      const nd = d + w;
      if (nd < (dist.get(n) ?? Infinity)) {
        dist.set(n, nd);
        pq.push([nd, n]);
      }
    }
  }
  return dist;
}
  • Time O((V+E) log V) with a binary heap.
  • Doesn't work with negative weights.

A* — with heuristic

Dijkstra + add a heuristic estimate to the priority. Heuristic must be admissible (never overestimates). For a grid: Manhattan or Euclidean distance to the goal.

MST

Kruskal

Sort edges by weight; add edge if it doesn't form a cycle (union-find).

Prim

Like Dijkstra but track "cheapest edge to add" — grow the MST one node at a time.

Topological sort

js
function topoSort(graph) {
  const inDegree = new Map();
  for (const node of Object.keys(graph)) inDegree.set(node, 0);
  for (const [node, neighbors] of Object.entries(graph)) {
    for (const n of neighbors) inDegree.set(n, (inDegree.get(n) ?? 0) + 1);
  }
  const queue = [...inDegree.entries()].filter(([_, d]) => d === 0).map(([n]) => n);
  const order = [];
  while (queue.length) {
    const node = queue.shift();
    order.push(node);
    for (const n of graph[node]) {
      inDegree.set(n, inDegree.get(n) - 1);
      if (inDegree.get(n) === 0) queue.push(n);
    }
  }
  return order.length === Object.keys(graph).length ? order : null;   // null = cycle
}

Interview framing

"Map the problem to a canonical shape, then pick the algorithm. Shortest path with no weights: BFS. Weighted with non-negative edges: Dijkstra with a priority queue. With a heuristic (grid pathfinding): A*. Negative edges: Bellman-Ford. MST: Kruskal with union-find or Prim. Dependency ordering: topological sort via Kahn's or DFS post-order. Cycle / SCC / articulation point: DFS-with-coloring or Tarjan. The trick is recognizing the shape from the problem description — 'find the cheapest path', 'is there a route', 'order tasks by dependency', 'minimum cost to connect everything' — and picking the textbook algorithm rather than reinventing."

Follow-up questions

  • Why doesn't BFS work for weighted shortest path?
  • When would you choose A* over Dijkstra?
  • Walk through Kruskal vs Prim — when is each better?
  • How do you detect a cycle in a directed graph efficiently?

Common mistakes

  • BFS on weighted graphs.
  • Dijkstra on graphs with negative edges.
  • Forgetting the priority queue in Dijkstra — falls back to O(V²).
  • Treating undirected and directed cycle detection the same.

Performance considerations

  • Algorithm choice dominates. Dense vs sparse: matrix vs adjacency list. Heap implementation in Dijkstra (binary, Fibonacci) affects log factor.

Edge cases

  • Disconnected graphs.
  • Cycles in supposed DAGs (topological sort returns partial).
  • Multi-edge / self-loops.

Real-world examples

  • Map routing (Dijkstra/A*).
  • Build dependency graph (topological sort).
  • Network optimization (max flow).

Senior engineer discussion

Seniors classify problems by shape, pick textbook algorithms, articulate complexity, and don't reinvent unless the canonical fit needs adapting.

Related questions