use std::collections::HashMap;
#[derive(Debug)]
struct Graph {
vertices: Vec<char>,
edges: HashMap<(char, char), Option<u32>>, // (from, to) -> weight or None
directed: bool,
}
impl Graph {
fn new(directed: bool) -> Self {
Self {
vertices: Vec::new(),
edges: HashMap::new(),
directed,
}
}
fn add_vertex(&mut self, v: char) {
if !self.vertices.contains(&v) {
self.vertices.push(v);
}
}
fn add_edge(&mut self, from: char, to: char, weight: Option<u32>) {
self.add_vertex(from);
self.add_vertex(to);
self.edges.insert((from, to), weight);
if !self.directed {
self.edges.insert((to, from), weight); // add reverse edge for undirected
}
}
fn print_graph(&self) {
println!("Vertices: {:?}", self.vertices);
println!("Edges:");
for ((from, to), weight) in &self.edges {
match weight {
Some(w) => println!("{} -> {} (weight {})", from, to, w),
None => println!("{} -> {}", from, to),
}
}
}
}
fn main() {
let mut graph = Graph::new(true); // directed graph
graph.add_edge('A', 'B', None); // A -> B
graph.directed = false; // switch to undirected for next edge
graph.add_edge('B', 'C', None); // B <-> C
graph.directed = true; // back to directed
graph.add_edge('C', 'D', Some(5)); // C -> D with weight 5
graph.print_graph();
}self.edges.insert((from, to), weight);
Add edge from 'from' to 'to' with optional weight
if !self.directed {
self.edges.insert((to, from), weight); // add reverse edge for undirected
}
If graph is undirected, add reverse edge to simulate two-way connection
graph.add_edge('A', 'B', None);
Add directed edge A -> B
Switch graph to undirected mode
graph.add_edge('B', 'C', None);
Add undirected edge B <-> C
Switch graph back to directed mode
graph.add_edge('C', 'D', Some(5));
Add directed weighted edge C -> D with weight 5
Vertices: ['A', 'B', 'C', 'D']
Edges:
A -> B
B -> C
C -> B
C -> D (weight 5)