Talentd
FleetCode
Make and follow sheets.Sign in

Reorder Routes to Make All Paths Lead to the City Zero solution and explanation

MediumBreadth-First SearchDepth-First SearchGraph7 min read66.3% acceptanceUpdated 9 Apr 2026
Leetcode 1466 - REORDER ROUTES TO MAKE ALL PATHS LEAD TO THE CITY ZERONeetCode · 10:02 · 62K viewsWatch on YouTube
9 more videos on this problem
  1. Leetcode 1466 - REORDER ROUTES TO MAKE ALL PATHS LEAD TO THE CITY ZERONeetCode · 10:02 · 62K views
  2. Reorder Routes to Make All Paths Lead to the City Zero || Graphs || DFSAryan Mittal · 17:32 · 7K views
  3. Reorder Routes to Make All Paths Lead to the City Zero | Java | LeetCode - 1466 | The Code MateThe Code Mate · 18:24 · 3K views
  4. Reorder Routes to Make All Paths Lead to the City Zero #leetcode #leetcode75Deepti Talesra · 11:54 · 3K views
  5. LeetCode 1466 - Reorder Routes to Make All Paths Lead to the City Zero - Python SolutionCode with Carter · 11:14 · 1K views
  6. Reorder Routes to Make All Paths Lead to the City Zero - Leetcode 1466 - PythonTechError · 9:29 · 1K views
  7. Daily Leetcode #1088: Mar 24, 2023 - 1466. Reorder Routes to Make All Paths Lead to the City ZeroProgramming Live with Larry · 6:51 · 1K views
  8. REORDER ROUTES TO MAKE ALL PATHS LEAD TO THE CITY ZERO | LEETCODE 1466 | PYTHON BFS SOLUTIONCracking FAANG · 15:54 · 885 views
  9. 1466. Reorder Routes to Make All Paths Lead to the City Zero (python) (Leetcode Medium)Programming Live with Larry · 7:51 · 545 views
  10. LeetCode 1466. Reorder Routes to Make All Paths Lead to the City ZeroJSer · 20:17 · 434 views

The problem

There are n cities numbered from 0 to n - 1 and n - 1 roads such that there is only one way to travel between two different cities (this network form a tree). Last year, The ministry of transport decided to orient the roads in one direction because they are too narrow.

Roads are represented by connections where connections[i] = [ai, bi] represents a road from city ai to city bi.

This year, there will be a big event in the capital (city 0), and many people want to travel to this city.

Your task consists of reorienting some roads such that each city can visit the city 0. Return the minimum number of edges changed.

It's guaranteed that each city can reach city 0 after reorder.

Example 1:

Input: n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
Output: 3
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 2:

Input: n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
Output: 2
Explanation: Change the direction of edges show in red such that each node can reach the node 0 (capital).

Example 3:

Input: n = 3, connections = [[1,0],[2,0]]
Output: 0

Constraints:

  • 2 <= n <= 5 * 104
  • connections.length == n - 1
  • connections[i].length == 2
  • 0 <= ai, bi <= n - 1
  • ai != bi

Approach overview

Problem Overview: You are given n cities connected by n - 1 directed roads forming a tree. Some roads point away from city 0. The goal is to reverse the minimum number of roads so every city has a path leading to city 0. The core challenge is detecting which edges point in the wrong direction when traversing from the capital.

Approach 1: Depth First Search (DFS) with Edge Direction Tracking (O(n) time, O(n) space)

Convert the directed graph into an adjacency list that keeps track of edge directions. For each connection (u, v), store two entries: (u → v, needsReversal = 1) and (v → u, needsReversal = 0). This representation allows traversal in both directions while remembering whether the original edge pointed away from city 0. Start a DFS from node 0, visiting neighbors while avoiding the parent node. Each time DFS follows an edge marked with needsReversal = 1, increment the counter because that road must be reversed to allow travel toward the capital.

This works because the underlying structure is a tree, so every edge is visited exactly once. DFS naturally explores the entire graph while accumulating the number of incorrect directions. The approach relies on standard Depth-First Search traversal over a graph representation.

Approach 2: Breadth First Search (BFS) with Direction Flags (O(n) time, O(n) space)

The BFS approach uses the same adjacency representation but processes nodes level by level starting from city 0. Initialize a queue with node 0 and mark it visited. For each node dequeued, iterate through its neighbors. If the stored direction flag indicates the edge originally pointed away from the current node toward the neighbor, it must be reversed, so increment the counter.

Each neighbor is then added to the queue if it has not been visited. Because the graph is a tree with n - 1 edges, BFS visits each node once and inspects each edge once, resulting in linear time. This version is often easier to reason about when you prefer iterative traversal using a queue. It follows the classic pattern of Breadth-First Search on graphs while tracking edge orientation.

Recommended for interviews: Both DFS and BFS achieve the optimal O(n) time complexity since every node and edge is processed once. Interviewers typically expect the DFS solution because it is concise and demonstrates strong understanding of graph traversal and edge direction modeling. Showing the adjacency trick (storing both directions with a cost flag) demonstrates that you can convert a directed tree into a traversal-friendly structure. BFS is equally valid and often preferred in iterative implementations.

Approach 1: Using Depth First Search (DFS)

To solve this problem, we can use a Depth First Search (DFS) starting from the capital city (city 0). During this traversal, we'll count the roads that need to be reordered.

We perform a DFS from city 0. For every road from a city a to b, we check if it's currently directed from 0 to n-1. If so, we need to count it as a reordering. Otherwise, we just traverse further.

def minReorder(n, connections):
    neighbors = {i: [] for i in range(n)}
    for u, v in connections:
        neighbors[u].append((v, 1)) # Indicates original direction u->v
        neighbors[v].append((u, 0)) # Virtual reverse direction

    def dfs(node, parent):
        reorder_count = 0
        for neighbor, direction in neighbors[node]:
            if neighbor == parent:
                continue
            reorder_count += direction + dfs(neighbor, node)
        return reorder_count

    return dfs(0, -1)
function minReorder(n, connections) {
    const graph = Array.from({length: n}, () => []);
    for (const [u, v] of connections) {
        graph[u].push([v, 1]); // original direction
        graph[v].push([u, 0]); // virtual reverse
    }

    function dfs(city, parent) {
        let changes = 0;
        for (const [next, direction] of graph[city]) {
            if (next !== parent) {
                changes += direction + dfs(next, city);
            }
        }
        return changes;
    }

    return dfs(0, -1);
}

We initialize an adjacency list to store each city's connections, differentiating directed and undirected edges. Starting from city 0, for each adjacent city, if the edge is directed away from the current city, we count it. We use a recursive DFS function to traverse the graph, keeping track of the parent to avoid cycles.

Complexity

Time Complexity: O(n), where n is the number of cities, as each node is visited exactly once.

Space Complexity: O(n), the space used for the recursion stack and storing the graph structure.

Try this approach in the editor

Approach 2: Breadth First Search (BFS)

An alternate approach using BFS begins at the capital city 0. We iterate over the child nodes, making direction checks immediately. This iterative form may help memory constraints on deep trees. We change direction whenever a node is reached by an edge that has to be flipped to reach city 0.

import java.util.*;

public int minReorder(int n, int[][] connections) {
    Map<Integer, List<int[]>> graph = new HashMap<>();
    for (int i = 0; i < n; i++) {
        graph.put(i, new ArrayList<>());
    }
    for (int[] con : connections) {
        graph.get(con[0]).add(new int[] {con[1], 1}); // direct
        graph.get(con[1]).add(new int[] {con[0], 0}); // reverse
    }

    Queue<Integer> queue = new LinkedList<>();
    boolean[] visited = new boolean[n];
    visited[0] = true;
    queue.add(0);

    int changes = 0;
    while (!queue.isEmpty()) {
        int current = queue.poll();
        for (int[] neighbor : graph.get(current)) {
            if (!visited[neighbor[0]]) {
                visited[neighbor[0]] = true;
                changes += neighbor[1];
                queue.add(neighbor[0]);
            }
        }
    }

    return changes;
}
#include <vector>
#include <queue>

using namespace std;

int minReorder(int n, vector<vector<int>>& connections) {
    vector<vector<pair<int, int>>> graph(n);
    for (const auto& con : connections) {
        graph[con[0]].emplace_back(con[1], 1);
        graph[con[1]].emplace_back(con[0], 0);
    }
    queue<int> q;
    vector<bool> visited(n, false);
    visited[0] = true;
    q.push(0);
    int reorders = 0;

    while (!q.empty()) {
        int node = q.front(); q.pop();
        for (const auto& [next, direction] : graph[node]) {
            if (!visited[next]) {
                visited[next] = true;
                reorders += direction;
                q.push(next);
            }
        }
    }

    return reorders;
}

We use a combination of adjacency list and iteration technique to explore each connection. Using queue mechanics, we ensure all cities are traversed, counting misaligned roads during traversal. Each road’s actual direction is evaluated for correct orientation.

Complexity

Time Complexity: O(n) - each node and edge is inspected once through BFS.

Space Complexity: O(n) - inherent to data storage structures and BFS queue.

Try this approach in the editor

Approach 3: DFS

The route map given in the problem has n nodes and n-1 edges. If we ignore the direction of the edges, then these n nodes form a tree. The problem requires us to change the direction of some edges so that each node can reach node 0.

We might as well consider starting from node 0 and reaching all other nodes. The direction is opposite to the problem description, which means that when we build the graph, for the directed edge [a, b], we should regard it as the directed edge [b, a]. That is to say, if it is from a to b, we need to change the direction once; if it is from b to a, no direction change is needed.

Next, we only need to start from node 0, search all other nodes, and during the process, if we encounter an edge that needs to change direction, we accumulate the number of direction changes once.

The time complexity is O(n), and the space complexity is O(n). Here, n is the number of nodes in the problem.

function minReorder(n: number, connections: number[][]): number {
    const g: [number, number][][] = Array.from({ length: n }, () => []);
    for (const [a, b] of connections) {
        g[a].push([b, 1]);
        g[b].push([a, 0]);
    }
    const dfs = (a: number, fa: number): number => {
        let ans = 0;
        for (const [b, c] of g[a]) {
            if (b !== fa) {
                ans += c + dfs(b, a);
            }
        }
        return ans;
    };
    return dfs(0, -1);
}
func minReorder(n int, connections [][]int) int {
	g := make([][][2]int, n)
	for _, e := range connections {
		a, b := e[0], e[1]
		g[a] = append(g[a], [2]int{b, 1})
		g[b] = append(g[b], [2]int{a, 0})
	}
	var dfs func(int, int) int
	dfs = func(a, fa int) (ans int) {
		for _, e := range g[a] {
			if b, c := e[0], e[1]; b != fa {
				ans += c + dfs(b, a)
			}
		}
		return
	}
	return dfs(0, -1)
}
impl Solution {
    pub fn min_reorder(n: i32, connections: Vec<Vec<i32>>) -> i32 {
        let mut g: Vec<Vec<(i32, i32)>> = vec![vec![]; n as usize];
        for e in connections.iter() {
            let a = e[0] as usize;
            let b = e[1] as usize;
            g[a].push((b as i32, 1));
            g[b].push((a as i32, 0));
        }
        fn dfs(a: usize, fa: i32, g: &Vec<Vec<(i32, i32)>>) -> i32 {
            let mut ans = 0;
            for &(b, c) in g[a].iter() {
                if b != fa {
                    ans += c + dfs(b as usize, a as i32, g);
                }
            }
            ans
        }
        dfs(0, -1, &g)
    }
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Using Depth First Search (DFS)

Time Complexity: O(n), where n is the number of cities, as each node is visited exactly once.

Space Complexity: O(n), the space used for the recursion stack and storing the graph structure.

Breadth First Search (BFS)

Time Complexity: O(n) - each node and edge is inspected once through BFS.

Space Complexity: O(n) - inherent to data storage structures and BFS queue.

DFS–

Complexity analysis

ApproachTimeSpaceWhen to Use
DFS with Edge Direction TrackingO(n)O(n)Most common interview solution. Concise recursion and natural tree traversal.
BFS with Direction FlagsO(n)O(n)Useful when preferring iterative traversal or avoiding recursion depth issues.

Frequently asked questions

Is Reorder Routes to Make All Paths Lead to the City Zero easy or hard?

The problem is classified as Medium on LeetCode. The main difficulty is recognizing that the graph forms a tree and modeling edge direction so traversal can detect which roads need reversal. Once the adjacency list with direction flags is built, the solution becomes a straightforward DFS or BFS with O(n) complexity.

Reorder Routes to Make All Paths Lead to the City Zero Python/Java solution

Python implementations typically use DFS with recursion and adjacency lists built using dictionaries or lists. Java solutions often use BFS with a queue and ArrayList-based adjacency lists. Both implementations follow the same idea of storing direction flags and counting edges that must be reversed during traversal.

How to solve Reorder Routes to Make All Paths Lead to the City Zero in O(n)?

Construct an adjacency list that stores both directions for every road with a direction flag. Run DFS or BFS starting from city 0 and traverse the entire tree. Whenever you move along an edge that originally goes away from the current node, increment the reversal count. Because the graph is a tree with n-1 edges, this traversal processes each edge once, achieving O(n) time.

What is the best approach for Reorder Routes to Make All Paths Lead to the City Zero?

The optimal approach is graph traversal using DFS or BFS while tracking edge direction. Build an adjacency list that stores both directions of every road along with a flag indicating whether the edge needs reversal. Starting from city 0, traverse the graph and count edges that originally point away from the capital. This solution runs in O(n) time and O(n) space.

Is Reorder Routes to Make All Paths Lead to the City Zero asked at Google/Amazon/Meta?

Graph traversal problems similar to this appear frequently in interviews at companies like Amazon, Google, and Meta. The problem tests your understanding of graph modeling, tree traversal, and edge direction handling using DFS or BFS. Variations involving edge reversals and reachability are common in system design and algorithm interviews.

What data structure is used in Reorder Routes to Make All Paths Lead to the City Zero?

The primary data structure is an adjacency list representing the graph. Each entry stores a neighbor and a flag indicating whether the road direction needs reversal. A visited set or boolean array prevents revisiting nodes during DFS or BFS traversal.

What is the time complexity of Reorder Routes to Make All Paths Lead to the City Zero?

The optimal DFS or BFS solution runs in O(n) time where n is the number of cities. Each city is visited once and each road is processed once during traversal. The space complexity is O(n) due to the adjacency list and the recursion stack or queue used during traversal.

Comments

Now write it yourselfClose this page and solve Reorder Routes to Make All Paths Lead to the City Zero in the editor, without looking.
Practise Reorder Routes to Make All Paths Lead to the City Zero