New
This commit is contained in:
140
Exercise/P2097 资料分发 1.rs
Normal file
140
Exercise/P2097 资料分发 1.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
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;
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user