#ifndef DIGRAPH_H_ #define DIGRAPH_H_ #include "algorithm/breadth_first_search.h" #include "graph.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); template friend std::ostream &operator<<(std::ostream &os, const 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