use std::{collections::HashSet, fs};
use crate::generate_vec_with;
pub mod acyclic_sp;
pub mod bellman_for_sp;
pub mod connect;
pub mod cycle;
pub mod depth_first_order;
pub mod dijkstra_sp;
pub mod directed_dfs;
pub mod edge_weighted;
pub mod topological;
type Bag = HashSet<usize>;
#[macro_export]
macro_rules! add_edge_weighted_for_digraph {
($g:ident,$v:expr, $w:expr,$weight:expr) => {
($g.add_edge($crate::digraph::edge_weighted::DirectedEdge::new(
$v, $w, $weight,
)))
};
}
pub struct Digraph {
vertex_count: usize,
edge_count: usize,
adj: Vec<Bag>,
}
impl Digraph {
pub fn new(vertex_count: usize) -> Self {
let adj = generate_vec_with!(Bag::new(), vertex_count);
Digraph {
vertex_count,
edge_count: 0,
adj,
}
}
pub fn vertex_count(&self) -> usize {
self.vertex_count
}
pub fn adge_count(&self) -> usize {
self.edge_count
}
pub fn add_edge(&mut self, v: usize, w: usize) {
self.adj[v].insert(w);
self.edge_count += 1;
}
pub fn adj(&self, v: usize) -> &Bag {
&self.adj[v]
}
pub fn reverse(&self) -> Self {
let mut r = Digraph::new(self.vertex_count);
for v in 0..self.vertex_count {
for w in &self.adj[v] {
r.add_edge(*w, v);
}
}
r
}
}
impl Digraph {
pub fn print_dot(&self, path: &str) {
self.print_dot_with(path, None)
}
pub fn print_dot_with(&self, path: &str, labels: Option<Vec<String>>) {
let mut graph = r#"digraph{
label="graph"
bgcolor=grey
shape=circle
"#
.to_string();
if let Some(labels) = labels {
labels.iter().enumerate().for_each(|(i, label)| {
graph.push_str(&format!("\t{}[label=\"{}\"]\n", i, label));
});
}
for v in 0..self.vertex_count {
for w in self.adj(v).clone() {
graph.push_str(&format!("{} -> {}\n", v, w));
}
}
graph.push('}');
let _ = fs::write(path, graph);
}
}