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