Files
rust/Exercise/P2097 资料分发 1.rs
e2hang dbc73e1a4f New
2025-10-08 22:56:01 +08:00

140 lines
3.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::io;
pub mod graph {
// 定义容器结构体:节点数量 + 邻接表
pub struct Container {
pub num: usize,
pub adj: Vec<Vec<usize>>,
pub parent: Vec<usize>, // 并查集父节点
}
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<usize>, x: usize) -> usize {
if parent[x] != x {
parent[x] = find(parent, parent[x]);
}
parent[x]
}
fn merge(parent: &mut Vec<usize>, 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::<Vec<_>>();
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<int> 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;
}
*/