Pagini recente » Cod sursa (job #3366539) | Cod sursa (job #3367759) | Cod sursa (job #3367047) | Cod sursa (job #3367548) | Cod sursa (job #3367095)
use std::collections::{HashSet, VecDeque};
use std::hash::{DefaultHasher, Hash, Hasher};
use std::io::Write;
struct Graf<const N: usize> {
graf: [Vec<usize>; N],
nodes: Vec<usize>,
}
impl<const N: usize> Graf<N> {
fn from_edges(edges: &[(usize, usize)], n: usize) -> Self {
let mut graf = std::array::from_fn(|_| Vec::new());
let nodes = (1..=n).collect();
for (x, y) in edges {
graf[*x].push(*y);
graf[*y].push(*x);
}
Self { graf, nodes }
}
fn vecini(&self, nod: usize) -> &[usize] {
self.graf[nod].as_ref()
}
fn get_nodes(&self) -> &[usize] {
&self.nodes
}
fn componenta_bfs(&self, nod: usize) -> u64 {
// ar fi fost mai frumost hashset dar na
let mut visied = Vec::new();
let mut queue = VecDeque::new();
queue.push_back(nod);
while let Some(current) = queue.pop_front() {
visied.push(current);
let vecini = self.vecini(current);
let visit_next = vecini.iter().filter(|x| !visied.contains(x));
for x in visit_next {
queue.push_back(*x);
}
}
let mut hasher = DefaultHasher::new();
visied.sort_unstable();
visied.hash(&mut hasher);
hasher.finish()
}
}
fn line_to_two_numbers(line: &str) -> (usize, usize) {
let stuff: Vec<usize> = line
.split_whitespace()
.map(|x| x.parse().unwrap())
.collect();
(stuff[0], stuff[1])
}
fn read_graph() -> Result<Graf<10000>, Box<dyn std::error::Error>> {
let input = std::fs::read_to_string("dfs.in")?;
let mut input = input.lines();
let (n, m) = line_to_two_numbers(input.next().unwrap());
let edges: Vec<_> = (0..m)
.map(|_| line_to_two_numbers(input.next().unwrap()))
.collect();
Ok(Graf::from_edges(&edges, n))
}
fn write_answer(answer: usize) {
let mut file = std::fs::File::create("dfs.out").unwrap();
let _ = write!(file, "{answer}");
}
fn main() {
let g = read_graph().unwrap();
let components_hashes: HashSet<u64> =
g.get_nodes().iter().map(|x| g.componenta_bfs(*x)).collect();
let count = components_hashes.len();
write_answer(count);
}