Graphs
Find City with Fewest Reachable
DESCRIPTION (inspired by Leetcode.com)
A regional planning committee wants to identify the most "isolated" city in a road network. Given n cities connected by bidirectional roads with varying distances, find the city that can reach the fewest other cities within a given distance threshold.
If multiple cities have the same minimum count, return the city with the highest number.
Note: The distance between two cities is the shortest path distance considering all possible routes.
Example 1:
Input:
n = 4 edges = [[0,1,3], [1,2,1], [1,3,4], [2,3,1]] distanceThreshold = 4
Output:
3
Explanation: After computing shortest paths, city 3 can reach cities 1 (distance 2) and 2 (distance 1) within the threshold — 2 reachable. City 0 can also reach 2 cities, but city 3 wins the tie by having the highest number.
Example 2:
Input:
n = 5 edges = [[0,1,2], [0,4,8], [1,2,3], [1,4,2], [2,3,1], [3,4,1]] distanceThreshold = 2
Output:
0
Explanation: With threshold 2, city 0 can only reach city 1 (distance 2). Other cities can reach more neighbors. City 0 has the fewest reachable.
public class Solution {
public Integer findTheCity(Integer n, int[][] edges, Integer distanceThreshold) {
// Your code goes here
}
}Run your code to see results here
Have suggestions or found something wrong?
Explanation
Understanding the Problem
A regional planning committee wants to identify the most "isolated" city in a road network for building a new data center. The ideal location minimizes connectivity to reduce network congestion risks. Given a network of cities connected by bidirectional roads with travel distances, find the city that can reach the fewest other cities within a given distance threshold.
With a threshold of 4, each city can reach different numbers of neighbors:
- City 0: reaches cities 1 (dist 3) and 2 (dist 4) → 2 reachable
- City 1: reaches cities 0 (dist 3), 2 (dist 1), 3 (dist 2) → 3 reachable
- City 2: reaches cities 0 (dist 4), 1 (dist 1), 3 (dist 1) → 3 reachable
- City 3: reaches cities 1 (dist 2) and 2 (dist 1) → 2 reachable ← tied with city 0, but highest number wins!
Cities 0 and 3 are tied with 2 reachable each. The tie-breaking rule says return the highest-numbered city, so city 3 is our answer.
Why This Differs from Previous Problems
In Network Delay Time, we needed shortest paths from one source to all nodes. Dijkstra was perfect. In Cheapest Flights, we needed shortest path from one source to one destination with constraints where some modification in Dijkstra worked.
But here, we need shortest paths from every city to every other city. Running Dijkstra n times for each node will give us the result, but there's a more optimised approach: Floyd-Warshall.
The Floyd-Warshall Approach
Floyd-Warshall finds shortest paths between all pairs of vertices using dynamic programming. The idea is that for each pair (i, j), we check if going through an intermediate vertex k gives a shorter path or not.
The algorithm iterates through all possible intermediate vertices k, and for each k, checks if it provides a shorter path for every pair (i, j).
The Algorithm Step by Step
- Initialize: dist[i][j] = edge weight if edge exists, 0 if i=j, ∞ otherwise
- For each intermediate vertex k (outer loop):
- For each source i (middle loop):
- For each destination j (inner loop):
- If dist[i][k] + dist[k][j] < dist[i][j], update dist[i][j]
- For each destination j (inner loop):
- For each source i (middle loop):
- Count reachable: For each city, count how many cities are within threshold
- Return: City with minimum reachable count (highest numbered if tied)
The order of loops is critical in Floyd-Warshall. The intermediate vertex k must be the outermost loop. This ensures that when we consider paths through vertex k, we've already computed the best paths using vertices 0 to k-1.
Walkthrough
Let's trace through with 4 cities, edges [[0,1,3], [1,2,1], [1,3,4], [2,3,1]], and threshold 4.
Step 1: Initialize Distance Matrix
Start with direct edge weights. Diagonal is 0, missing edges are ∞.
Step 2: Process k=0, k=1, k=2, k=3
For each intermediate vertex, check if routing through it improves any path. After processing k=1:
- dist[0][2] updates: 0→2 was ∞, but 0→1→2 = 3+1 = 4
- dist[0][3] updates: 0→3 was ∞, but 0→1→3 = 3+4 = 7
After processing k=2:
- dist[0][3] updates again: 0→2→3 = 4+1 = 5 (better than 7)
- dist[1][3] updates: 1→2→3 = 1+1 = 2 (better than direct 4)
Step 3: Count Reachable Cities (threshold=4)
After Floyd-Warshall completes, for each city count neighbors within threshold:
Cities 0 and 3 tie with 2 reachable each. Tie-breaking picks the highest-numbered city, so return 3.
Tie-breaking rule: If multiple cities have the same minimum reachable count, return the city with the highest number. This is why we iterate from 0 to n-1 and update the answer whenever we find a city with count ≤ current minimum.
When to Use Floyd-Warshall vs. Running Dijkstra n Times
| Scenario | Floyd-Warshall | n × Dijkstra |
|---|---|---|
| Time complexity | O(V³) | O(V · (V+E) log V) |
| Dense graph (E ≈ V²) | O(V³) ✓ | O(V³ log V) |
| Sparse graph (E ≈ V) | O(V³) | O(V² log V) ✓ |
| Simple implementation | ✓ Three nested loops | More complex |
| Works with negative edges | ✓ (no negative cycles) | ✗ |
For this problem, V ≤ 100, so Floyd-Warshall's O(V³) = O(10⁶) is fast enough and simpler to implement.
Solution
The solution applies Floyd-Warshall to compute all-pairs shortest paths, then counts reachable cities for each city:
- Initialize distance matrix from edges (bidirectional, so set both directions)
- Run Floyd-Warshall to find all shortest paths
- Count reachable cities within threshold for each city
- Return city with minimum count (highest number if tied)
public int findTheCity(int n, int[][] edges, int threshold) {int INF = (int) 1e9;int[][] dist = new int[n][n];for (int i = 0; i < n; i++) {Arrays.fill(dist[i], INF);dist[i][i] = 0;}// Fill in direct edges (bidirectional)for (int[] e : edges) {dist[e[0]][e[1]] = Math.min(dist[e[0]][e[1]], e[2]);dist[e[1]][e[0]] = Math.min(dist[e[1]][e[0]], e[2]);}// Floyd-Warshall: try each vertex as intermediatefor (int k = 0; k < n; k++) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (dist[i][k] + dist[k][j] < dist[i][j]) {dist[i][j] = dist[i][k] + dist[k][j];}}}}// Find city with fewest reachable within thresholdint result = 0, minReachable = n;for (int city = 0; city < n; city++) {int count = 0;for (int j = 0; j < n; j++) {if (city != j && dist[city][j] <= threshold) count++;}if (count <= minReachable) {minReachable = count;result = city;}}return result;}
Initialize distance matrix: diagonal = 0, all others = ∞
0 / 21
What is the time complexity of this solution?
O(m * n * 4^L)
O(V³)
O(m * n)
O(4^L)