#ifndef DIGRAPH_H_ #define DIGRAPH_H_ #include "graph.h" #include "algorithm/breadth_first_search.h" namespace graph { template class Digraph : public Graph { public: Digraph() = default; explicit Digraph(std::unordered_map> G); // Return true if there is a path from u to v bool contains(const T& u, const T& v); // Add edge e(u,v) void insert(const T& u, const T& v); // Remove edge e(u,v) void remove(const T& u, const T& v); // Reverse graph directions auto reverse(); // auto contains(const T& u); friend std::ostream& operator<<<>(std::ostream& os, Digraph& G); }; template Digraph::Digraph(std::unordered_map> G) { this->adjList = G; } template bool Digraph::contains(const T& u, const T& v) { return algo::BreadthFirstSearch(this->adjList).query(u, v); } template void Digraph::insert(const T& u, const T& v) { this->adjList[u].insert(v); this->adjList[v]; } template void Digraph::remove(const T& u, const T& v) { this->adjList[u].erase(v); } template auto Digraph::reverse() { std::unordered_map> revMatrix; for (const auto& u : this->vertices()) { for (const auto& v : this->adjList[u]) { revMatrix[v].insert(u); } } return revMatrix; } template auto Digraph::contains(const T& u) { return this->adjList.count(u); } template std::ostream& operator<<(std::ostream& os, Digraph& G) { os << "V: " << G.V() << " E: " << G.E() << '\n'; for (const auto& u : G.vertices()) { if (!G.adjList[u].empty()) { for (const auto& v : G.adjList[u]) { os << u << "->" << v << ' '; } os << '\n'; } } os << '\n'; return os; } } // namespace graph #endif