use std::io; pub mod graph { // 定义容器结构体:节点数量 + 邻接表 pub struct Container { pub num: usize, pub adj: Vec>, pub parent: Vec, // 并查集父节点 } impl Container { // 初始化图和并查集 pub fn new(n: usize) -> Self { let mut parent = vec![0; n]; for i in 0..n { parent[i] = i; } Self { num: n, adj: vec![vec![]; n], parent, } } // 查找根节点(带路径压缩) pub fn find(&mut self, i: usize) -> usize { if self.parent[i] != i { let root = self.find(self.parent[i]); self.parent[i] = root; } self.parent[i] } // 合并两个集合 pub fn merge(&mut self, i: usize, j: usize) { let fi = self.find(i); let fj = self.find(j); if fi != fj { self.parent[fi] = fj; } } // 添加一条边 pub fn add_edge(&mut self, a: usize, b: usize) { self.adj[a].push(b); self.adj[b].push(a); // 如果是无向图 self.merge(a, b); // 顺便在并查集中合并 } // 打印邻接表 pub fn show(&self) { for (i, edges) in self.adj.iter().enumerate() { println!("{} -> {:?}", i, edges); } } // 判断两个节点是否连通 pub fn connected(&mut self, a: usize, b: usize) -> bool { self.find(a) == self.find(b) } } } fn main() { use graph::Container; // 示例:5个节点 let mut g = Container::new(5); g.add_edge(0, 1); g.add_edge(1, 2); g.add_edge(3, 4); g.show(); println!("0-2 connected? {}", g.connected(0, 2)); println!("0-4 connected? {}", g.connected(0, 4)); } use std::io::{self, Read}; fn find(parent: &mut Vec, x: usize) -> usize { if parent[x] != x { parent[x] = find(parent, parent[x]); } parent[x] } fn merge(parent: &mut Vec, a: usize, b: usize) { let fa = find(parent, a); let fb = find(parent, b); if fa != fb { parent[fb] = fa; } } fn main() { let mut input = String::new(); io::stdin().read_to_string(&mut input).unwrap(); let mut iter = input.split_whitespace(); let n: usize = iter.next().unwrap().parse().unwrap(); let m: usize = iter.next().unwrap().parse().unwrap(); let mut parent = (0..=n).collect::>(); for _ in 0..m { let a: usize = iter.next().unwrap().parse().unwrap(); let b: usize = iter.next().unwrap().parse().unwrap(); merge(&mut parent, a, b); } let mut roots = std::collections::HashSet::new(); for i in 1..=n { roots.insert(find(&mut parent, i)); } println!("{}", roots.len()); } /* 并查集 vector parent(n); for(int i = 0; i < n; i++){ parent[i] = i; } int find(int i){ if(parent[i] != i){ parent[i] = find(parent[i]); } return parent[i]; } void merge(int i, int j){ int fi = find(i); int fj = find(j); if(fi != fj) parent[j] = fi; } */