Find the City With the Smallest Number of Neighbors at a Threshold Distance

Updated on 27 May, 2025
Find the City With the Smallest Number of Neighbors at a Threshold Distance header image

Problem Statement

The task involves dealing with a network of n cities, represented by integers from 0 to n-1. The connectivity between these cities is specified by a list of edges, where each element in the list is denoted as [fromi, toi, weighti]. This specifies a bidirectional edge between cities fromi and toi with a weight of weighti, representing some form of cost, distance, or barrier to travel between these two cities. Additionally, a parameter distanceThreshold defines the maximum permissible travel cost between any two cities for them to be considered "reachable" from each other.

The objective is to identify a city from which the number of other reachable cities, under the constraint of distanceThreshold, is minimized. If this minimal count is the same for multiple cities, the city with the largest numerical identifier should be chosen. The distance between any two cities is cumulatively accounted for by the sum of edges' weights along any path traversed between them.

Examples

Example 1

Input:

n = 4, edges = [[0,1,3],[1,2,1],[1,3,4],[2,3,1]], distanceThreshold = 4

Output:

3

Explanation:

The figure above describes the graph. 
The neighboring cities at a distanceThreshold = 4 for each city are:
City 0 -> [City 1, City 2] 
City 1 -> [City 0, City 2, City 3] 
City 2 -> [City 0, City 1, City 3] 
City 3 -> [City 1, City 2] 
Cities 0 and 3 have 2 neighboring cities at a distanceThreshold = 4, but we have to return city 3 since it has the greatest 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:

The figure above describes the graph. 
The neighboring cities at a distanceThreshold = 2 for each city are:
City 0 -> [City 1] 
City 1 -> [City 0, City 4] 
City 2 -> [City 3, City 4] 
City 3 -> [City 2, City 4]
City 4 -> [City 1, City 2, City 3] 
The city 0 has 1 neighboring city at a distanceThreshold = 2.

Constraints

  • 2 <= n <= 100
  • 1 <= edges.length <= n * (n - 1) / 2
  • edges[i].length == 3
  • 0 <= fromi < toi < n
  • 1 <= weighti, distanceThreshold <= 10^4
  • All pairs (fromi, toi) are distinct.

Approach and Intuition

The problem essentially translates to finding paths in a weighted graph where the path's total weight does not exceed the given distanceThreshold.

  1. The connectivity between cities can be visualized as nodes and edges in a graph, where each node represents a city, and each edge represents a direct road (with a certain weight or distance cost) between two cities.
  2. Our aim is to determine the "reachability" of each city based on this network and the specified distanceThreshold.
  3. We can use algorithms like Floyd-Warshall or Dijkstra's algorithm (executed for each city) to compute the shortest paths between all pairs of cities:
    • Floyd-Warshall algorithm: This is a dynamic programming algorithm that computes the shortest paths between every pair of vertices in a weighted graph. It is apt for this problem because it provides a way to determine the shortest path between all pairs of nodes efficiently, especially under the constraint of n <= 100.
    • Dijkstra's algorithm: It can be used iteratively for each city to determine the distances to all other cities, and we count those that are within the distanceThreshold.
  4. After applying the shortest path algorithm, for each city, we would count the number of other cities that are reachable within the given distanceThreshold.
  5. We then select the city with the smallest count of reachable cities. If there's a tie (multiple cities with the same count), the city with the greater index (number) is chosen.

The computational feasibility of these approaches is supported by the constraints, making it a viable problem for typical graph traversal and shortest path algorithms.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    int findLeastConnectedCity(int cityCount, vector<vector<int>>& routes, int maxDistance) {
        // Maximum possible value for an unconnected path
        const int MAX_DIST = 1000000007;
        // Matrix to keep the minimum distances between any two cities
        vector<vector<int>> dist(cityCount, vector<int>(cityCount, MAX_DIST));

        // Set diagonal to zero since distance to self is always zero
        for (int i = 0; i < cityCount; i++) {
            dist[i][i] = 0;
        }

        // Set initial distances based on direct routes provided
        for (const auto& route : routes) {
            int src = route[0];
            int dest = route[1];
            int length = route[2];
            dist[src][dest] = length;
            dist[dest][src] = length;  // Because the graph is undirected
        }

        // Apply the Floyd-Warshall algorithm to find shortest paths
        computeAllPairsShortestPath(cityCount, dist);

        // Evaluate which city has the least cities within the given threshold
        return determineCityWithMinimalReachable(cityCount, dist, maxDistance);
    }

    void computeAllPairsShortestPath(int count, vector<vector<int>>& dist) {
        for (int k = 0; k < count; k++) {
            for (int i = 0; i < count; i++) {
                for (int j = 0; j < count; j++) {
                    if (dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                    }
                }
            }
        }
    }

    int determineCityWithMinimalReachable(int count, const vector<vector<int>>& dist, int threshold) {
        int optimalCity = -1;
        int minimalReachableCount = count;

        for (int i = 0; i < count; i++) {
            int countUnderThreshold = 0;
            for (int j = 0; j < count; j++) {
                if (i != j && dist[i][j] <= threshold) {
                    countUnderThreshold++;
                }
            }

            if (countUnderThreshold <= minimalReachableCount) {
                minimalReachableCount = countUnderThreshold;
                optimalCity = i;
            }
        }

        return optimalCity;
    }
};

This C++ solution addresses the problem of identifying a city with the minimum number of neighboring cities within a specified maximum distance threshold. The process involves the following key steps:

  1. Initialize a distance matrix to represent the minimum distances between any two cities. Initially, all values are set to a very high number (indicative of infinity), except for diagonal elements which are zero because the distance from a city to itself is always zero.

  2. Populate this matrix with the direct routes available between cities. Each entry in the routes vector contains the starting city, the destination city, and the distance between them.

  3. Utilize the Floyd-Warshall algorithm to compute the shortest paths between all pairs of cities. This algorithm updates the matrix such that for any two cities, it provides the shortest achievable distance based on the input routes and their connectivity.

  4. Calculate for each city the number of other cities that can be reached within the given distance threshold.

  5. Identify and return the index of the city with the smallest number of reachable cities (neighbors) within the specified distance threshold.

The functions computeAllPairsShortestPath and determineCityWithMinimalReachable are used to abstract the complexity of the Floyd-Warshall algorithm implementation and the calculation to determine the city with the least number of reachable neighboring cities, respectively.

This approach efficiently determines the optimal city by taking full advantage of the Floyd-Warshall algorithm's capability to find the minimum path costs between all pairs of nodes in a weighted graph. Essential checks ensure the solution is comprehensive, accounting for direct and indirect routes between the cities.

java
class Solution {

    public int findLeastConnectedCity(int totalCities, int[][] connections, int threshold) {
        int INFINITY = (int) 1e9 + 7;
        int[][] dist = new int[totalCities][totalCities];

        for (int i = 0; i < totalCities; i++) {
            Arrays.fill(dist[i], INFINITY);
            dist[i][i] = 0;
        }

        for (int[] connection : connections) {
            int from = connection[0];
            int to = connection[1];
            int len = connection[2];
            dist[from][to] = len;
            dist[to][from] = len;
        }

        runFloydWarshall(totalCities, dist);

        return determineCityWithLeastConnections(totalCities, dist, threshold);
    }

    void runFloydWarshall(int totalCities, int[][] dist) {
        for (int k = 0; k < totalCities; k++) {
            for (int i = 0; i < totalCities; i++) {
                for (int j = 0; j < totalCities; j++) {
                    dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }
    }

    int determineCityWithLeastConnections(int totalCities, int[][] dist, int threshold) {
        int cityWithLeastConnections = -1;
        int minimumConnectionCount = totalCities;

        for (int i = 0; i < totalCities; i++) {
            int count = 0;
            for (int j = 0; j < totalCities; j++) {
                if (i != j && dist[i][j] <= threshold) {
                    count++;
                }
            }
            if (count <= minimumConnectionCount) {
                minimumConnectionCount = count;
                cityWithLeastConnections = i;
            }
        }

        return cityWithLeastConnections;
    }
}

The Java solution provided targets determining the city with the minimum number of neighbors within a given threshold distance. By utilizing the Floyd-Warshall algorithm, the solution calculates the shortest paths between all pairs of cities from the weighted adjacency list of city connections.

The implementation follows these steps:

  1. Define the findLeastConnectedCity method accepting the total number of cities, a 2D array of city connections, and a threshold distance.
  2. Initialize a 2D distance array dist, setting distances to infinity for all city pairs except to themselves (distance zero).
  3. Transform the list of city connections into an adjacency matrix, updating the matrix with the given edge lengths (bi-directional).
  4. Pass the distance matrix to the runFloydWarshall method to compute the shortest path between all pairs of cities.
  5. Run the determineCityWithLeastConnections method, which evaluates each city for its number of connections below the given distance threshold.
  6. Iterate over each city and count connections that satisfy the threshold condition, ultimately finding the city with the least number of connections within the threshold limit.
  7. Return the identified city.

With a deep focus on efficiency, the Floyd-Warshall algorithm ensures that the shortest path between any pair of cities gets determined, applicable through dynamic programming. The overall approach, centered around minimum connectivity based on the threshold, ensures the solution is comprehensive and suitable for scenarios involving weighted graphs and path evaluations.

python
class Solution:
    def minimumDistanceCity(self, city_count: int, routes: List[List[int]], max_distance: int) -> int:
        # Setup a large number to represent infinite distance
        INFINITE_DIST = float('inf')
        # Initialize the distance matrix
        city_distances = [[INFINITE_DIST] * city_count for _ in range(city_count)]

        # Set zero distance to self
        for city in range(city_count):
            city_distances[city][city] = 0

        # Load the given routes into the distance matrix
        for start_city, end_city, travel_cost in routes:
            city_distances[start_city][end_city] = travel_cost
            city_distances[end_city][start_city] = travel_cost

        # Apply the Floyd-Warshall algorithm
        self.allPairsShortestPath(city_count, city_distances)

        # Determine the optimal city
        optimal_city = self.findOptimalCity(city_count, city_distances, max_distance)
        return optimal_city

    def allPairsShortestPath(self, city_count: int, distance_matrix: List[List[int]]) -> None:
        # Execute Floyd-Warshall update on distances
        for k in range(city_count):
            for i in range(city_count):
                for j in range(city_count):
                    if distance_matrix[i][j] > distance_matrix[i][k] + distance_matrix[k][j]:
                        distance_matrix[i][j] = distance_matrix[i][k] + distance_matrix[k][j]

    def findOptimalCity(self, city_count: int, distance_matrix: List[List[int]], max_distance: int) -> int:
        optimal_city = -1
        minimum_connectivity = city_count

        # Evaluate each city for minimal connectivity within threshold
        for i in range(city_count):
            count = sum(1 for j in range(city_count) if i != j and distance_matrix[i][j] <= max_distance)
            if count <= minimum_connectivity:
                minimum_connectivity = count
                optimal_city = i
        return optimal_city

The provided Python script solves the problem of identifying the city with the least number of neighbors within a given distance threshold. Here's a breakdown of how the solution is structured:

  • Initialization of Distance Matrix: A matrix city_distances is initialized where each element represents the distance between cities. Distances to self are set to zero and all other distances are initialized to infinity, symbolizing that they are unreachable until specified.

  • Loading Routes: The matrix is populated with the routes provided. Each route gives the distance between two cities, and since the graph is undirected, the distance is symmetric.

  • Floyd-Warshall Algorithm Implementation: This standard algorithm calculates the shortest paths between all pairs of nodes in a weighted graph. For each city triplet (i, j, k), the algorithm checks if a direct journey from i to j is longer than one going through k. If true, the shorter distance is updated in the matrix.

  • City Evaluation: Finally, the script iterates through each city, counting how many other cities can be reached from it within the specified max_distance. This count is then compared against all other cities to find the one with the smallest number of reachable neighbors.

  • Return Optimal City: The city with the smallest number of reachable neighbors under the given threshold is returned.

By using the Floyd-Warshall algorithm, all pairs of shortest paths are efficiently computed, ensuring that the city evaluation step has accurate data regarding city distances. The end result is the identification of a city optimal for its minimal reachability, catering to scenarios where isolation is preferred due to a distance constraint.

Comments

No comments yet.