pub fn dfs<K>(num_vertices: usize, edges: &[(usize, usize, K, usize)]) -> Vec<isize> {
let mut nbrs: Vec<Vec<usize>> = vec![Vec::new(); num_vertices];
for &(u, v, _, _) in edges {
nbrs[u].push(v);
nbrs[v].push(u);
}
let mut x = vec![-1isize; num_vertices];
let mut cc_id = 0isize;
let mut stack = Vec::new();
for start in 0..num_vertices {
if x[start] != -1 {
continue;
}
x[start] = cc_id;
stack.push(start);
while let Some(u) = stack.pop() {
for &v in &nbrs[u] {
if x[v] == -1 {
x[v] = cc_id;
stack.push(v);
}
}
}
cc_id += 1;
}
x
}
#[cfg(test)]
mod tests {
use super::dfs;
#[test]
fn test_dfs_two_components() {
let num_vertices = 5;
let edges: Vec<(usize, usize, i32, usize)> = vec![
(0, 1, 1, 0), (1, 2, 1, 1),
(3, 4, 1, 2), ];
let x = dfs(num_vertices, &edges);
assert_eq!(x.len(), num_vertices);
assert_eq!(x[0], x[1]);
assert_eq!(x[1], x[2]);
assert_eq!(x[3], x[4]);
assert_ne!(x[0], x[3]);
}
#[test]
fn test_dfs_line_graph() {
let num_vertices = 4;
let edges: Vec<(usize, usize, i32, usize)> = vec![
(0, 1, 5, 0), (1, 2, 6, 1),
(2, 3, 7, 2),
];
let x = dfs(num_vertices, &edges);
assert_eq!(x, vec![0, 0, 0, 0]);
}
#[test]
fn test_dfs_isolated_vertices() {
let num_vertices = 3;
let edges: Vec<(usize, usize, i32, usize)> = Vec::new();
let x = dfs(num_vertices, &edges);
assert_eq!(x, vec![0, 1, 2]);
}
#[test]
fn test_dfs_with_self_loop_and_multiple_ccs() {
let num_vertices = 6;
let edges: Vec<(usize, usize, i32, usize)> = vec![
(0, 1, 1, 0), (2, 3, 1, 1), (3, 2, 1, 1), (4, 4, 1, 2), ];
let x = dfs(num_vertices, &edges);
assert_eq!(x[0], x[1]); assert_eq!(x[2], x[3]); assert_ne!(x[0], x[2]);
assert_eq!(x[4], 2); assert_eq!(x[5], 3); }
}