Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# 2492. Minimum Score of a Path Between Two Cities

[LeetCode Link](https://leetcode.com/problems/minimum-score-of-a-path-between-two-cities/)

Difficulty: Medium
Topics: Depth-First Search, Breadth-First Search, Union-Find, Graph Theory
Acceptance Rate: 60.2%

## Hints

### Hint 1

The problem lets a path revisit cities and reuse roads as many times as you like. That freedom is a big clue: think carefully about what "path" really constrains here, and which category of graph problem this belongs to (connectivity, shortest path, minimum spanning tree, ...). It is not as complicated as the "path" wording first suggests.

### Hint 2

Because you can walk back and forth freely, any road that is reachable from city `1` within the same connected chunk of the graph can be included in your path. So the score is just the minimum-distance road among *all* roads you can possibly touch on a walk from `1` to `n`. Now ask: which roads are those?

### Hint 3

Since a path can wander anywhere within a connected component, the set of usable roads is exactly the set of roads belonging to the connected component that contains both city `1` and city `n` (the problem guarantees they are connected). The answer is the smallest `distance` among every road inside that component. You do not need any real "pathfinding" — you only need to explore the component reachable from city `1` and track the minimum edge weight seen.

## Approach

The key realization is that the word "path" is misleading. A path may repeat roads and revisit cities without limit, so once you can reach any road, you can incorporate its distance into your path's minimum. Therefore the score you can achieve is the minimum distance over the entire set of roads that lie in the connected component containing city `1`. The guarantee that `1` and `n` are connected means `n` is in that same component, so this minimum is valid for a `1`-to-`n` path.

This reduces to a simple graph traversal:

1. Build an adjacency list. For each road `[a, b, d]`, add `(b, d)` to `a`'s list and `(a, d)` to `b`'s list.
2. Starting from city `1`, run a BFS (or DFS) over the component. Whenever you traverse an edge, update a running `answer = min(answer, d)`.
3. Mark cities as visited so each is processed once; you still relax every incident edge's weight into the minimum.
4. Return `answer`.

Why it works: every road in the component is incident to some city reachable from `1`, so BFS will visit that city and see the road's weight. No road outside the component can ever be part of a walk from `1`, so ignoring those is correct.

Walkthrough of Example 1 (`n = 4`, roads `[[1,2,9],[2,3,6],[2,4,5],[1,4,7]]`): BFS from `1` reaches `2`, `3`, `4` — the whole graph is one component. The edge weights encountered are `9, 7, 6, 5`, and the minimum is `5`, which matches the expected output. Even though the shortest topological path `1 -> 2 -> 4` gives `min(9, 5) = 5`, we did not need to reason about specific paths — the component minimum gives the same answer directly.

A Union-Find alternative works too: union all roads, then take the minimum distance among roads whose endpoints share the root of city `1`. BFS/DFS is the most direct here.

## Complexity Analysis

Time Complexity: O(n + m), where `n` is the number of cities and `m = roads.length`. We build the adjacency list in O(m) and visit each vertex and edge a constant number of times during traversal.
Space Complexity: O(n + m) for the adjacency list, the visited array, and the BFS queue.

## Edge Cases

- **Disconnected graph with unrelated cheap roads:** A very cheap road in a component that does *not* contain city `1` must be ignored. Restricting the traversal to city `1`'s component handles this — a global minimum over all roads would be wrong.
- **Roads reusable / cities revisited:** The problem's allowance to repeat roads is exactly why component-minimum works; do not try to compute an actual simple path.
- **Minimum comes from an edge not on any direct `1 -> n` path:** As in Example 2, the answer edge (`1-2` with weight `2`) is a detour, not on a straightforward path to `n`. Tracking the component minimum captures it naturally.
- **Multiple edges between the same reachable region:** All incident edges are relaxed into the minimum, so the smallest is always found.
- **1-indexed cities:** Cities are numbered `1..n`; size arrays accordingly (or offset) to avoid off-by-one errors.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
number: "2492"
frontend_id: "2492"
title: "Minimum Score of a Path Between Two Cities"
slug: "minimum-score-of-a-path-between-two-cities"
difficulty: "Medium"
topics:
- "Depth-First Search"
- "Breadth-First Search"
- "Union-Find"
- "Graph Theory"
acceptance_rate: 6015.7
is_premium: false
created_at: "2026-07-04T04:09:08.688945+00:00"
fetched_at: "2026-07-04T04:09:08.688945+00:00"
link: "https://leetcode.com/problems/minimum-score-of-a-path-between-two-cities/"
date: "2026-07-04"
---

# 2492. Minimum Score of a Path Between Two Cities

You are given a positive integer `n` representing `n` cities numbered from `1` to `n`. You are also given a **2D** array `roads` where `roads[i] = [ai, bi, distancei]` indicates that there is a **bidirectional** road between cities `ai` and `bi` with a distance equal to `distancei`. The cities graph is not necessarily connected.

The **score** of a path between two cities is defined as the **minimum** distance of a road in this path.

Return _the**minimum** possible score of a path between cities _`1` _and_`n`.

**Note** :

* A path is a sequence of roads between two cities.
* It is allowed for a path to contain the same road **multiple** times, and you can visit cities `1` and `n` multiple times along the path.
* The test cases are generated such that there is **at least** one path between `1` and `n`.





**Example 1:**

![](https://assets.leetcode.com/uploads/2022/10/12/graph11.png)


**Input:** n = 4, roads = [[1,2,9],[2,3,6],[2,4,5],[1,4,7]]
**Output:** 5
**Explanation:** The path from city 1 to 4 with the minimum score is: 1 -> 2 -> 4. The score of this path is min(9,5) = 5.
It can be shown that no other path has less score.


**Example 2:**

![](https://assets.leetcode.com/uploads/2022/10/12/graph22.png)


**Input:** n = 4, roads = [[1,2,2],[1,3,4],[3,4,7]]
**Output:** 2
**Explanation:** The path from city 1 to 4 with the minimum score is: 1 -> 2 -> 1 -> 3 -> 4. The score of this path is min(2,2,4,7) = 2.




**Constraints:**

* `2 <= n <= 105`
* `1 <= roads.length <= 105`
* `roads[i].length == 3`
* `1 <= ai, bi <= n`
* `ai != bi`
* `1 <= distancei <= 104`
* There are no repeated edges.
* There is at least one path between `1` and `n`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

// Problem 2492: Minimum Score of a Path Between Two Cities.
//
// Because a path may repeat roads and revisit cities without limit, any road in
// the connected component containing city 1 can be included in a walk from 1 to n
// (which are guaranteed connected). The best achievable score is therefore the
// minimum edge distance across every road in that component.
//
// Approach: build an adjacency list, BFS the component starting at city 1, and
// track the minimum edge weight encountered. Runs in O(n + m).
func minScore(n int, roads [][]int) int {
type edge struct {
to, dist int
}

adj := make([][]edge, n+1)
for _, r := range roads {
a, b, d := r[0], r[1], r[2]
adj[a] = append(adj[a], edge{b, d})
adj[b] = append(adj[b], edge{a, d})
}

const maxDist = 1<<31 - 1
answer := maxDist

visited := make([]bool, n+1)
queue := []int{1}
visited[1] = true

for len(queue) > 0 {
city := queue[0]
queue = queue[1:]

for _, e := range adj[city] {
if e.dist < answer {
answer = e.dist
}
if !visited[e.to] {
visited[e.to] = true
queue = append(queue, e.to)
}
}
}

return answer
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import "testing"

func TestMinScore(t *testing.T) {
tests := []struct {
name string
n int
roads [][]int
expected int
}{
{
name: "example 1: single component, min edge is 5",
n: 4,
roads: [][]int{{1, 2, 9}, {2, 3, 6}, {2, 4, 5}, {1, 4, 7}},
expected: 5,
},
{
name: "example 2: answer edge is a detour off the direct path",
n: 4,
roads: [][]int{{1, 2, 2}, {1, 3, 4}, {3, 4, 7}},
expected: 2,
},
{
name: "edge case: single road directly connects 1 and n",
n: 2,
roads: [][]int{{1, 2, 42}},
expected: 42,
},
{
name: "edge case: cheap road in another component is ignored",
n: 5,
roads: [][]int{{1, 2, 8}, {2, 5, 6}, {3, 4, 1}},
expected: 6,
},
{
name: "edge case: minimum comes from the last relaxed edge",
n: 5,
roads: [][]int{{1, 2, 10}, {2, 3, 9}, {3, 4, 8}, {4, 5, 3}},
expected: 3,
},
{
name: "edge case: duplicate-weight edges, smallest wins",
n: 3,
roads: [][]int{{1, 2, 5}, {2, 3, 5}, {1, 3, 4}},
expected: 4,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := minScore(tt.n, tt.roads)
if result != tt.expected {
t.Errorf("minScore(%d, %v) = %d, want %d", tt.n, tt.roads, result, tt.expected)
}
})
}
}