int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if (source == target) return 0;
vector<pair<int, int>> queue{{source, 0}};
unordered_set<int> seen{source};
for (size_t head = 0; head < queue.size(); head++) {
auto [stop, buses] = queue[head];
for (auto& route : routes) {
if (find(route.begin(), route.end(), stop) == route.end()) continue;
for (int next : route) {
if (next == target) return buses + 1;
if (!seen.count(next)) { seen.insert(next); queue.push_back({next, buses + 1}); }
}
}
}
return -1;
}
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) return 0;
List<int[]> queue = new ArrayList<>(); queue.add(new int[]{source, 0});
Set<Integer> seen = new HashSet<>(); seen.add(source);
for (int head = 0; head < queue.size(); head++) {
int stop = queue.get(head)[0], buses = queue.get(head)[1];
for (int[] route : routes) {
boolean serves = false;
for (int s : route) if (s == stop) { serves = true; break; }
if (!serves) continue;
for (int next : route) {
if (next == target) return buses + 1;
if (seen.add(next)) queue.add(new int[]{next, buses + 1});
}
}
}
return -1;
}
def num_buses_to_destination(routes, source, target):
if source == target: return 0
queue = [(source, 0)]
seen = {source}
head = 0
while head < len(queue):
stop, buses = queue[head]; head += 1
for route in routes:
if stop not in route: continue
for nxt in route:
if nxt == target: return buses + 1
if nxt not in seen:
seen.add(nxt); queue.append((nxt, buses + 1))
return -1
function numBusesToDestination(routes: number[][], source: number, target: number): number {
if (source === target) return 0;
const queue: [number, number][] = [[source, 0]];
const seen = new Set<number>([source]);
for (let head = 0; head < queue.length; head++) {
const [stop, buses] = queue[head];
for (const route of routes) {
if (!route.includes(stop)) continue;
for (const next of route) {
if (next === target) return buses + 1;
if (!seen.has(next)) { seen.add(next); queue.push([next, buses + 1]); }
}
}
}
return -1;
}
int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if (source == target) return 0;
unordered_map<int, vector<int>> stopRoutes;
for (int r = 0; r < (int)routes.size(); r++) {
for (int stop : routes[r]) {
stopRoutes[stop].push_back(r);
}
}
vector<pair<int, int>> queue{{source, 0}};
unordered_set<int> seen{source};
for (size_t head = 0; head < queue.size(); head++) {
auto [stop, buses] = queue[head];
for (int r : stopRoutes[stop]) {
for (int next : routes[r]) {
if (next == target) return buses + 1;
if (!seen.count(next)) { seen.insert(next); queue.push_back({next, buses + 1}); }
}
}
}
return -1;
}
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) return 0;
Map<Integer, List<Integer>> stopRoutes = new HashMap<>();
for (int r = 0; r < routes.length; r++) {
for (int stop : routes[r]) {
stopRoutes.computeIfAbsent(stop, k -> new ArrayList<>()).add(r);
}
}
List<int[]> queue = new ArrayList<>(); queue.add(new int[]{source, 0});
Set<Integer> seen = new HashSet<>(); seen.add(source);
for (int head = 0; head < queue.size(); head++) {
int stop = queue.get(head)[0], buses = queue.get(head)[1];
for (int r : stopRoutes.getOrDefault(stop, new ArrayList<>())) {
for (int next : routes[r]) {
if (next == target) return buses + 1;
if (seen.add(next)) queue.add(new int[]{next, buses + 1});
}
}
}
return -1;
}
def num_buses_to_destination(routes, source, target):
if source == target: return 0
stop_routes = defaultdict(list)
for r, route in enumerate(routes):
for stop in route:
stop_routes[stop].append(r)
queue = [(source, 0)]
seen = {source}
head = 0
while head < len(queue):
stop, buses = queue[head]; head += 1
for r in stop_routes.get(stop, []):
for nxt in routes[r]:
if nxt == target: return buses + 1
if nxt not in seen:
seen.add(nxt); queue.append((nxt, buses + 1))
return -1
function numBusesToDestination(routes: number[][], source: number, target: number): number {
if (source === target) return 0;
const stopRoutes = new Map<number, number[]>();
routes.forEach((route, r) => {
for (const stop of route) {
if (!stopRoutes.has(stop)) stopRoutes.set(stop, []);
stopRoutes.get(stop)!.push(r);
}
});
const queue: [number, number][] = [[source, 0]];
const seen = new Set<number>([source]);
for (let head = 0; head < queue.length; head++) {
const [stop, buses] = queue[head];
for (const r of stopRoutes.get(stop) ?? []) {
for (const next of routes[r]) {
if (next === target) return buses + 1;
if (!seen.has(next)) { seen.add(next); queue.push([next, buses + 1]); }
}
}
}
return -1;
}
int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if (source == target) return 0;
unordered_map<int, vector<int>> stopRoutes;
for (int r = 0; r < (int)routes.size(); r++) {
for (int stop : routes[r]) {
stopRoutes[stop].push_back(r);
}
}
vector<pair<int, int>> queue{{source, 0}};
unordered_set<int> seen{source};
unordered_set<int> usedRoute;
for (size_t head = 0; head < queue.size(); head++) {
auto [stop, buses] = queue[head];
for (int r : stopRoutes[stop]) {
if (usedRoute.count(r)) continue;
usedRoute.insert(r);
for (int next : routes[r]) {
if (next == target) return buses + 1;
if (!seen.count(next)) { seen.insert(next); queue.push_back({next, buses + 1}); }
}
}
}
return -1;
}
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) return 0;
Map<Integer, List<Integer>> stopRoutes = new HashMap<>();
for (int r = 0; r < routes.length; r++) {
for (int stop : routes[r]) {
stopRoutes.computeIfAbsent(stop, k -> new ArrayList<>()).add(r);
}
}
List<int[]> queue = new ArrayList<>(); queue.add(new int[]{source, 0});
Set<Integer> seen = new HashSet<>(); seen.add(source);
Set<Integer> usedRoute = new HashSet<>();
for (int head = 0; head < queue.size(); head++) {
int stop = queue.get(head)[0], buses = queue.get(head)[1];
for (int r : stopRoutes.getOrDefault(stop, new ArrayList<>())) {
if (usedRoute.contains(r)) continue;
usedRoute.add(r);
for (int next : routes[r]) {
if (next == target) return buses + 1;
if (seen.add(next)) queue.add(new int[]{next, buses + 1});
}
}
}
return -1;
}
def num_buses_to_destination(routes, source, target):
if source == target: return 0
stop_routes = defaultdict(list)
for r, route in enumerate(routes):
for stop in route:
stop_routes[stop].append(r)
queue = [(source, 0)]
seen = {source}
used_route = set()
head = 0
while head < len(queue):
stop, buses = queue[head]; head += 1
for r in stop_routes.get(stop, []):
if r in used_route: continue
used_route.add(r)
for nxt in routes[r]:
if nxt == target: return buses + 1
if nxt not in seen:
seen.add(nxt); queue.append((nxt, buses + 1))
return -1
function numBusesToDestination(routes: number[][], source: number, target: number): number {
if (source === target) return 0;
const stopRoutes = new Map<number, number[]>();
routes.forEach((route, r) => {
for (const stop of route) {
if (!stopRoutes.has(stop)) stopRoutes.set(stop, []);
stopRoutes.get(stop)!.push(r);
}
});
const queue: [number, number][] = [[source, 0]];
const seen = new Set<number>([source]);
const usedRoute = new Set<number>();
for (let head = 0; head < queue.length; head++) {
const [stop, buses] = queue[head];
for (const r of stopRoutes.get(stop) ?? []) {
if (usedRoute.has(r)) continue;
usedRoute.add(r);
for (const next of routes[r]) {
if (next === target) return buses + 1;
if (!seen.has(next)) { seen.add(next); queue.push([next, buses + 1]); }
}
}
}
return -1;
}
int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if (source == target) return 0;
unordered_map<int, vector<int>> stopRoutes;
for (int r = 0; r < (int)routes.size(); r++) {
for (int stop : routes[r]) {
stopRoutes[stop].push_back(r);
}
}
if (!stopRoutes.count(source) || !stopRoutes.count(target)) return -1;
vector<char> taken(routes.size(), 0);
unordered_set<int> seenStop{source};
vector<int> level = stopRoutes[source];
for (int r : level) taken[r] = 1;
int buses = 1;
while (!level.empty()) {
vector<int> nextLevel;
for (int r : level) {
for (int stop : routes[r]) {
if (stop == target) return buses;
if (seenStop.count(stop)) continue;
seenStop.insert(stop);
for (int r2 : stopRoutes[stop]) {
if (!taken[r2]) { taken[r2] = 1; nextLevel.push_back(r2); }
}
}
}
level = nextLevel;
buses++;
}
return -1;
}
public int numBusesToDestination(int[][] routes, int source, int target) {
if (source == target) return 0;
Map<Integer, List<Integer>> stopRoutes = new HashMap<>();
for (int r = 0; r < routes.length; r++) {
for (int stop : routes[r]) {
stopRoutes.computeIfAbsent(stop, k -> new ArrayList<>()).add(r);
}
}
if (!stopRoutes.containsKey(source) || !stopRoutes.containsKey(target)) return -1;
boolean[] taken = new boolean[routes.length];
Set<Integer> seenStop = new HashSet<>(); seenStop.add(source);
List<Integer> level = new ArrayList<>(stopRoutes.get(source));
for (int r : level) taken[r] = true;
int buses = 1;
while (!level.isEmpty()) {
List<Integer> nextLevel = new ArrayList<>();
for (int r : level) {
for (int stop : routes[r]) {
if (stop == target) return buses;
if (seenStop.contains(stop)) continue;
seenStop.add(stop);
for (int r2 : stopRoutes.get(stop)) {
if (!taken[r2]) { taken[r2] = true; nextLevel.add(r2); }
}
}
}
level = nextLevel;
buses++;
}
return -1;
}
def num_buses_to_destination(routes, source, target):
if source == target: return 0
stop_routes = defaultdict(list)
for r, route in enumerate(routes):
for stop in route:
stop_routes[stop].append(r)
if source not in stop_routes or target not in stop_routes: return -1
taken = [False] * len(routes)
seen_stop = {source}
level = list(stop_routes[source])
for r in level: taken[r] = True
buses = 1
while level:
next_level = []
for r in level:
for stop in routes[r]:
if stop == target: return buses
if stop in seen_stop: continue
seen_stop.add(stop)
for r2 in stop_routes[stop]:
if not taken[r2]:
taken[r2] = True; next_level.append(r2)
level = next_level
buses += 1
return -1
function numBusesToDestination(routes: number[][], source: number, target: number): number {
if (source === target) return 0;
const stopRoutes = new Map<number, number[]>();
routes.forEach((route, r) => {
for (const stop of route) {
const list = stopRoutes.get(stop);
if (list) list.push(r); else stopRoutes.set(stop, [r]);
}
});
if (!stopRoutes.has(source) || !stopRoutes.has(target)) return -1;
const taken = new Uint8Array(routes.length);
const seenStop = new Set<number>([source]);
let level: number[] = [...stopRoutes.get(source)!];
for (const r of level) taken[r] = 1;
let buses = 1;
while (level.length > 0) {
const nextLevel: number[] = [];
for (const r of level) {
for (const stop of routes[r]) {
if (stop === target) return buses;
if (seenStop.has(stop)) continue;
seenStop.add(stop);
for (const r2 of stopRoutes.get(stop)!) {
if (!taken[r2]) { taken[r2] = 1; nextLevel.push(r2); }
}
}
}
level = nextLevel;
buses++;
}
return -1;
}