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