Shortest Distance After Road Addition Queries I

MEDIUM

Description

You are given an integer n and a 2D integer array queries.

There are n cities numbered from 0 to n - 1. Initially, there is a unidirectional road from city i to city i + 1 for all 0 <= i < n - 1.

queries[i] = [ui, vi] represents the addition of a new unidirectional road from city ui to city vi. After each query, you need to find the length of the shortest path from city 0 to city n - 1.

Return an array answer where for each i in the range [0, queries.length - 1], answer[i] is the length of the shortest path from city 0 to city n - 1 after processing the first i + 1 queries.

 

Example 1:

Input: n = 5, queries = [[2,4],[0,2],[0,4]]

Output: [3,2,1]

Explanation:

After the addition of the road from 2 to 4, the length of the shortest path from 0 to 4 is 3.

After the addition of the road from 0 to 2, the length of the shortest path from 0 to 4 is 2.

After the addition of the road from 0 to 4, the length of the shortest path from 0 to 4 is 1.

Example 2:

Input: n = 4, queries = [[0,3],[0,2]]

Output: [1,1]

Explanation:

After the addition of the road from 0 to 3, the length of the shortest path from 0 to 3 is 1.

After the addition of the road from 0 to 2, the length of the shortest path remains 1.

 

Constraints:

  • 3 <= n <= 500
  • 1 <= queries.length <= 500
  • queries[i].length == 2
  • 0 <= queries[i][0] < queries[i][1] < n
  • 1 < queries[i][1] - queries[i][0]
  • There are no repeated roads among the queries.

Approaches

Checkout 3 different approaches to solve Shortest Distance After Road Addition Queries I. Click on different approaches to view the approach and algorithm in detail.

Brute Force with Floyd-Warshall

This approach recalculates the shortest paths between all pairs of cities after each query using the Floyd-Warshall algorithm. While it correctly finds the shortest path from city 0 to city n-1, it's highly inefficient because it computes much more information than required.

Algorithm

  • For each query i from 0 to queries.length - 1:
    1. Create an n x n distance matrix dist, initialized with infinity, except for dist[j][j] = 0.
    2. Populate dist with initial edges: dist[j][j+1] = 1 for 0 <= j < n-1.
    3. Populate dist with query edges from 0 to i: dist[u][v] = 1 for each query [u, v].
    4. Apply the Floyd-Warshall algorithm to compute all-pairs shortest paths.
    5. Store dist[0][n-1] as the answer for query i.

The Floyd-Warshall algorithm is a dynamic programming approach to find the shortest paths between all pairs of vertices in a weighted directed graph. For each query, we construct a distance matrix representing the graph at that stage. The algorithm works as follows:

  1. Initialize an n x n distance matrix dist. dist[i][j] is 1 if there's a direct road from i to j, 0 if i == j, and infinity otherwise.
  2. The initial roads i -> i+1 are added to the matrix.
  3. For the k-th query, all roads from queries[0] to queries[k] are added.
  4. The Floyd-Warshall algorithm is then run on this matrix. It iterates through all possible intermediate vertices k for each pair of source i and destination j, and updates the shortest path dist[i][j] if the path through k is shorter.
  5. After the algorithm completes, dist[0][n-1] contains the length of the shortest path from city 0 to city n-1. This process is repeated for every single query.
class Solution {
    public int[] shortestDistanceAfterQueries(int n, int[][] queries) {
        int[] answer = new int[queries.length];
        java.util.List<int[]> currentEdges = new java.util.ArrayList<>();

        for (int i = 0; i < queries.length; i++) {
            currentEdges.add(queries[i]);
            
            long[][] dist = new long[n][n];
            for (int r = 0; r < n; r++) {
                java.util.Arrays.fill(dist[r], Integer.MAX_VALUE);
                dist[r][r] = 0;
            }

            // Add initial edges
            for (int j = 0; j < n - 1; j++) {
                dist[j][j + 1] = 1;
            }

            // Add query edges
            for (int[] edge : currentEdges) {
                dist[edge[0]][edge[1]] = 1;
            }

            // Floyd-Warshall algorithm
            for (int k = 0; k < n; k++) {
                for (int u = 0; u < n; u++) {
                    for (int v = 0; v < n; v++) {
                        if (dist[u][k] != Integer.MAX_VALUE && dist[k][v] != Integer.MAX_VALUE) {
                            dist[u][v] = Math.min(dist[u][v], dist[u][k] + dist[k][v]);
                        }
                    }
                }
            }
            answer[i] = (int) dist[0][n - 1];
        }
        return answer;
    }
}

Complexity Analysis

Time Complexity: O(Q * n^3), where `Q` is the number of queries and `n` is the number of cities. For each of the `Q` queries, we run Floyd-Warshall which takes `O(n^3)` time.Space Complexity: O(n^2) to store the distance matrix for each query.

Pros and Cons

Pros:
  • Conceptually simple if one is familiar with the Floyd-Warshall algorithm.
Cons:
  • Extremely inefficient due to its high time complexity.
  • Recomputes all-pairs shortest paths from scratch for every query, which is massive overkill for this problem.
  • Will result in a 'Time Limit Exceeded' error for the given constraints.

Code Solutions

Checking out 3 solutions in different languages for Shortest Distance After Road Addition Queries I. Click on different languages to view the code.


Video Solution

Watch the video walkthrough for Shortest Distance After Road Addition Queries I



Algorithms:

Breadth-First Search

Data Structures:

ArrayGraph

Subscribe to Scale Engineer newsletter

Learn about System Design, Software Engineering, and interview experiences every week.

No spam, unsubscribe at any time.