// https://infoarena.ro/problema/dfs
use std::{
collections::*, fmt::*, fs::{write, *}, str::*
};
fn split_in_x_var<T: FromStr>(string: &str) -> Vec<T> where T::Err: Debug {
string.split_whitespace().map(|x| x.parse::<T>().unwrap()).collect::<Vec<T>>()
}
fn split_in_x<const N: usize, T: FromStr + Debug>(string: &str) -> [T; N] where T::Err: Debug {
string.split_whitespace().map(|x| x.parse::<T>().unwrap()).collect::<Vec<T>>().try_into().unwrap()
}
fn bfs(nod_start: usize, nod_de_gasit: usize, nodurile: &Vec<HashSet<usize>>) -> Option<usize> {
if nod_start == nod_de_gasit {
return Some(0);
}
let mut gasite_tot = HashSet::from([nod_start]);
let mut gasite = HashSet::from([nod_start]);
for lungime in 1.. {
let mut gasite_noi = HashSet::<usize>::new();
for gasit in &gasite {
if nodurile[*gasit].contains(&nod_de_gasit) {
return Some(lungime);
}
gasite_noi.extend(&nodurile[*gasit]);
}
if gasite_noi.difference(&gasite_tot).last().is_none() {
return None;
}
gasite_tot.extend(&gasite_noi);
gasite = gasite_noi;
}
return None
}
fn main() {
let content = read_to_string("bfs.in").unwrap();
let mut lines = content.lines();
let [noduri, _muchii, mut nod]: [usize; 3] = split_in_x(lines.next().unwrap());
nod -= 1;
let mut nodurile = vec![HashSet::new(); noduri];
for line in lines {
let [muchie1, muchie2]: [usize; 2] = split_in_x(line);
nodurile[muchie1 - 1].insert(muchie2 - 1);
}
let numbers = (0..noduri)
.map(|nod_de_gasit| bfs(nod, nod_de_gasit, &nodurile)
.map(|x| x as isize).unwrap_or(-1).to_string());
let res = numbers.collect::<Vec<_>>().join(" ");
write("bfs.out", res).unwrap();
}