Problem: Find the City With the Smallest Number of Neighbors at a Threshold Distance
The knowledge points outside of my skill tree
Explanation of Code and Concepts
-
What is
float('inf')
?float('inf')
in Python represents positive infinity. It is used to initialize distances to a very large number (effectively infinity) so that they can be replaced by any shorter actual distance found during the algorithm’s execution. This is particularly useful in graph algorithms like Floyd-Warshall where you need a way to represent the concept of “no direct path” between nodes.
-
Matrix Initialization:
dist = [[float('inf')] * n for _ in range(n)]
- This line of code initializes a 2D list (matrix)
dist
of sizen x n
where each element is set tofloat('inf')
. Here’s a breakdown of its components:for _ in range(n)
: This is a list comprehension that iteratesn
times. The variable_
is conventionally used when the actual value of the variable is not needed.* n
: This creates a list containingn
elements, all initialized tofloat('inf')
. When you write[float('inf')] * n
, it means create a list withn
elements, each of which isfloat('inf')
.[[float('inf')] * n for _ in range(n)]
: The list comprehension iteratesn
times, creatingn
lists, each containingn
elements offloat('inf')
. This results in ann x n
matrix where all entries are initially set tofloat('inf')
.
- This line of code initializes a 2D list (matrix)
Description
There are n
cities numbered from 0
to n-1
. Given an array edges
where edges[i] = [fromi, toi, weighti]
represents a bidirectional and weighted edge between cities fromi
and toi
, and given an integer distanceThreshold
, return the city with the smallest number of cities that are reachable through some path and whose distance is at most distanceThreshold
. If there are multiple such cities, return the city with the greatest number.
The distance of a path connecting cities i
and j
is equal to the sum of the edges’ weights along that path.
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 neighboring cities at a distanceThreshold
of 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
of 4, but we 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 neighboring cities at a distanceThreshold
of 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]
City 0 has 1 neighboring city at a distanceThreshold
of 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.
Solution
Approach
-
Initialize the Distance Matrix:
- Create an
n x n
matrixdist
wheredist[i][j]
represents the shortest distance from cityi
to cityj
. - Initialize
dist[i][i]
to 0 for all cities. - Initialize
dist[i][j]
toinfinity
for all pairs of citiesi
andj
that do not have a direct edge. - Set
dist[i][j]
to the weight of the edge between citiesi
andj
for all given edges.
- Create an
-
Run the Floyd-Warshall Algorithm:
- For each intermediate city
k
, and for each pair of citiesi
andj
, updatedist[i][j]
to be the minimum of its current value and the sum of the distances fromi
tok
and fromk
toj
.
- For each intermediate city
-
Count Reachable Cities:
- For each city, count how many other cities can be reached with a distance less than or equal to the
distanceThreshold
.
- For each city, count how many other cities can be reached with a distance less than or equal to the
-
Find the Desired City:
- Find the city with the smallest number of reachable cities.
- In case of a tie, select the city with the greatest numerical value.
Python Code
class Solution(object):
def findTheCity(self, n, edges, distanceThreshold):
"""
:type n: int
:type edges: List[List[int]]
:type distanceThreshold: int
:rtype: int
"""
# Initialize the distance matrix with infinity
dist = [[float('inf')] * n for _ in range(n)]
# Distance to itself is 0
for i in range(n):
dist[i][i] = 0
# Set initial distances based on the edges
for u, v, w in edges:
dist[u][v] = w
dist[v][u] = w
# Floyd-Warshall algorithm to find shortest paths
for k in range(n):
for i in range(n):
for j in range(n):
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
# Find the number of reachable cities for each city
min_count = float('inf')
result_city = -1
for i in range(n):
count = sum(1 for j in range(n) if dist[i][j] <= distanceThreshold)
# If count is the same, choose the city with the larger number
if count < min_count or (count == min_count and i > result_city):
min_count = count
result_city = i
return result_city
Explanation
-
Distance Initialization:
- Initialize the distance matrix with
float('inf')
to represent no direct path between cities, except for the diagonal (distance to itself), which is set to 0. - Update the initial distances based on the provided edges.
- Initialize the distance matrix with
-
Floyd-Warshall Algorithm:
- Iteratively update the shortest paths between all pairs of cities by considering each city as an intermediate node.
-
Counting Reachable Cities:
- Count the number of cities that are reachable from each city within the
distanceThreshold
.
- Count the number of cities that are reachable from each city within the
-
Selecting the Optimal City:
- Determine the city with the smallest number of reachable cities. In case of a tie, select the city with the larger numerical value.