use fxhash::{FxHashMap, FxHashSet};
use std::{hash::Hash, collections::HashMap, ops::Add};
pub type Vertex = u32;
pub type Edge = (Vertex, Vertex);
pub type Arc = (Vertex, Vertex);
pub type VertexSet = FxHashSet<Vertex>;
pub type MixedSet = FxHashSet<VertexOrEdge>;
pub type VertexMap<T> = FxHashMap<Vertex, T>;
pub type VertexSetRef<'a> = FxHashSet<&'a Vertex>;
pub type MixedSetRef<'a> = FxHashSet<&'a VertexOrEdge>;
pub type EdgeSet = FxHashSet<Edge>;
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub enum VertexOrEdge {
V(Vertex),
E(Edge)
}
impl VertexOrEdge {
pub fn as_vertex(self) -> Option<Vertex> {
match self {
VertexOrEdge::V(v) => Some(v),
VertexOrEdge::E(_) => None,
}
}
pub fn is_vertex(self) -> bool {
match self {
VertexOrEdge::V(_) => true,
VertexOrEdge::E(_) => false,
}
}
pub fn is_edge(self) -> bool {
match self {
VertexOrEdge::V(_) => false,
VertexOrEdge::E(_) => true,
}
}
pub fn as_edge(self) -> Option<Edge> {
match self {
VertexOrEdge::V(_) => None,
VertexOrEdge::E(e) => Some(e),
}
}
}
pub trait Graph {
fn num_vertices(&self) -> usize;
fn num_edges(&self) -> usize;
fn contains(&self, u:&Vertex) -> bool;
fn adjacent(&self, u:&Vertex, v:&Vertex) -> bool;
fn degree(&self, u:&Vertex) -> u32;
fn degrees(&self) -> VertexMap<u32> {
let mut res = VertexMap::default();
for v in self.vertices() {
res.insert(*v, self.degree(v));
}
res
}
fn len(&self) -> usize {
self.num_vertices()
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn vertices<'a>(&'a self) -> Box<dyn Iterator<Item=&Vertex> + 'a>;
fn neighbours<'a>(&'a self, u:&Vertex) -> Box<dyn Iterator<Item=&Vertex> + 'a>;
fn neighbourhood<'a, I>(&self, vertices:I) -> FxHashSet<Vertex>
where I: Iterator<Item=&'a Vertex>, Vertex: 'a {
let mut res:FxHashSet<Vertex> = FxHashSet::default();
let centers:FxHashSet<Vertex> = vertices.cloned().collect();
for v in ¢ers {
res.extend(self.neighbours(v).cloned());
}
res.retain(|u| !centers.contains(u));
res
}
fn closed_neighbourhood<'a, I>(&self, vertices:I) -> FxHashSet<Vertex>
where I: Iterator<Item=&'a Vertex>, Vertex: 'a {
let mut res:FxHashSet<Vertex> = FxHashSet::default();
for v in vertices {
res.extend(self.neighbours(v).cloned());
}
res
}
fn r_neighbours(&self, u:&Vertex, r:usize) -> FxHashSet<Vertex> {
self.r_neighbourhood([*u].iter(), r)
}
fn r_neighbourhood<'a,I>(&self, vertices:I, r:usize) -> FxHashSet<Vertex>
where I: Iterator<Item=&'a Vertex>, Vertex: 'a {
let mut res:FxHashSet<Vertex> = FxHashSet::default();
res.extend(vertices.cloned());
for _ in 0..r {
let ext = self.closed_neighbourhood(res.iter());
res.extend(ext);
}
res
}
fn subgraph<'a, M, I>(&self, vertices:I) -> M
where M: MutableGraph, I: Iterator<Item=&'a Vertex> {
let selected:VertexSet = vertices.cloned().collect();
let mut G = M::with_capacity(selected.len());
for v in &selected {
G.add_vertex(v);
let Nv:VertexSet = self.neighbours(v).cloned().collect();
for u in Nv.intersection(&selected) {
G.add_edge(u, v);
}
}
G
}
}
pub trait MutableGraph: Graph{
fn new() -> Self;
fn with_capacity(n: usize) -> Self;
fn add_vertex(&mut self, u: &Vertex) -> bool;
fn remove_vertex(&mut self, u: &Vertex) -> bool;
fn add_edge(&mut self, u: &Vertex, v: &Vertex) -> bool;
fn remove_edge(&mut self, u: &Vertex, v: &Vertex) -> bool;
fn add_vertices(&mut self, vertices: impl Iterator<Item=Vertex>) -> u32 {
let mut count = 0;
for v in vertices {
if self.add_vertex(&v) {
count += 1;
}
}
count
}
fn add_edges(&mut self, edges: impl Iterator<Item=Edge>) -> u32 {
let mut count = 0;
for (u,v) in edges {
if self.add_edge(&u, &v) {
count += 1;
}
}
count
}
fn remove_loops(&mut self) -> usize {
let mut cands = Vec::new();
for u in self.vertices() {
if self.adjacent(u, u) {
cands.push(*u)
}
}
let res = cands.len();
for u in cands.into_iter() {
self.remove_edge(&u, &u);
}
res
}
fn remove_isolates(&mut self) -> usize {
let cands:Vec<_> = self.vertices().filter(|&u| self.degree(u) == 0).cloned().collect();
let res = cands.len();
for u in cands.into_iter() {
self.remove_vertex(&u);
}
res
}
}
pub trait Digraph: Graph {
fn has_arc(&self, u:&Vertex, v:&Vertex) -> bool;
fn in_degree(&self, u:&Vertex) -> u32 {
self.in_neighbours(u).count() as u32
}
fn out_degree(&self, u:&Vertex) -> u32 {
self.out_neighbours(u).count() as u32
}
fn in_degrees(&self) -> VertexMap<u32> {
let mut res = VertexMap::default();
for v in self.vertices() {
res.insert(*v, self.in_degree(v));
}
res
}
fn out_degrees(&self) -> VertexMap<u32> {
let mut res = VertexMap::default();
for v in self.vertices() {
res.insert(*v, self.out_degree(v));
}
res
}
fn neighbours<'a>(&'a self, u:&Vertex) -> Box<dyn Iterator<Item=&Vertex> + 'a> {
Box::new(self.in_neighbours(u).chain(self.out_neighbours(u)))
}
fn out_neighbours<'a>(&'a self, u:&Vertex) -> Box<dyn Iterator<Item=&Vertex> + 'a>;
fn in_neighbours<'a>(&'a self, u:&Vertex) -> Box<dyn Iterator<Item=&Vertex> + 'a>;
}
pub trait MutableDigraph: Digraph {
fn new() -> Self;
fn add_vertex(&mut self, u: &Vertex) -> bool;
fn remove_vertex(&mut self, u: &Vertex) -> bool;
fn add_arc(&mut self, u: &Vertex, v: &Vertex) -> bool;
fn remove_arc(&mut self, u: &Vertex, v: &Vertex) -> bool;
}
pub trait LinearGraph : Graph {
fn index_of(&self, u:&Vertex) -> usize;
fn left_neighbours(&self, u:&Vertex) -> Vec<Vertex>;
fn right_degree(&self, u:&Vertex) -> u32;
fn left_degree(&self, u:&Vertex) -> u32 {
if self.contains(u) {
self.left_neighbours(u).len() as u32
} else {
0
}
}
fn left_degrees(&self) -> VertexMap<u32> {
let mut res = VertexMap::default();
for u in self.vertices() {
res.insert(*u, self.left_degree(u));
}
res
}
fn max_left_degree(&self) -> u32 {
self.vertices().map(|u| self.left_degree(u)).max().unwrap_or(0)
}
fn right_degrees(&self) -> VertexMap<u32> {
let mut res = VertexMap::default();
for u in self.vertices() {
res.insert(*u, self.right_degree(u));
}
res
}
fn max_right_degree(&self) -> u32 {
self.vertices().map(|u| self.right_degree(u)).max().unwrap_or(0)
}
}