#ifndef KING_H_ #define KING_H_ #include "algorithm/dynamic_reachability.h" #include "algorithm/italiano.h" using namespace graph; namespace algo { template class King : public DynamicReachability { public: King() = default; King(Digraph G) { this->G = G; } // Initialize decremental maintenance data structures for DAGs for each // vertex's in and out reachability trees void init() override; // Execute reachability query q(u, v) from vertex u to vertex v // in O(n) using the stored decremental maintenance data structure for DAGs bool query(const T& u, const T& v) override; // Delete edge e(u, v) from all reachability trees and update each one of // them using the decremental reachability algorithm for DAGs void remove(const T& u, const T& v) override; // Insert edge e(u, v) by reconstructing all reachability trees void insert(const T& u, const T& v) override; private: // Connect each reachabiliy tree with decremental maintenance data structure std::map> In; std::map> Out; }; template void King::init() { for (const auto& u : this->G.vertices()) { In[u] = Italiano(BreadthFirstTree(this->G.reverse(), u)); In[u].init(); Out[u] = Italiano(BreadthFirstTree(this->G, u)); Out[u].init(); } } template bool King::query(const T& u, const T& v) { return std::any_of(this->G.vertices().begin(), this->G.vertices().end(), [&](const T& w) { return In[w].query(w, u) && Out[w].query(w, v); }); } template void King::remove(const T& u, const T& v) { this->G.remove(u, v); for (const auto& w : this->G.vertices()) { In[w].remove(v, u); Out[w].remove(u, v); } } template void King::insert(const T& u, const T& v) { this->G.insert(u, v); init(); } } // namespace algo #endif