diff --git a/algorithm/henzinger_king.h b/algorithm/henzinger_king.h new file mode 100644 index 0000000..f6d90a1 --- /dev/null +++ b/algorithm/henzinger_king.h @@ -0,0 +1,79 @@ +#ifndef HENZINGER_KING_H_ +#define HENZINGER_KING_H_ + +#include "algorithm/dynamic_reachability.h" +#include "algorithm/frigioni.h" + +using namespace graph; + +namespace algo { + +template +class HenzingerKing : public DynamicReachability { +public: + HenzingerKing() = default; + + HenzingerKing(Digraph G) { this->G = G; } + + // 1. Initialize a decremental reachability data structure. + // 2. Let S <- phi. + + // In the beginning of each phase, a decremental reachability data structure + // is initialized. We let S be the set of vertices that were centers of + // insertions during this phase. Initially S = phi. When a set of edges Ev, all + // touching v, is inserted, we add v to S and construct reachability trees In(v) + // and Out(v) rooted at v. When the size of S, the set of insertion centers, + // reaches t, a parameter fixed in advance, the phase is declared over, and + // all the data structures are reinitialized. + void init() override; + + // 1. Query the decremental reachability data structure. + // 2. For each w in S check if u in In(w) and v in Out(w). + + // First the decremental data structure is queried to see whether there is a + // directed path from u to v composed solely of edges that were present in the + // graph at the start of the current phase. If not, it is checked whether there + // exists w in S such that u in In(w) and v in Out(w). If such a vertex w exists, + // then the answer is YES. + bool query(const T& u, const T& v) override; + + // 1. Let E <- E - E'. + // 2. Delete E' from the decremental data structure. + // 3. For every w in S, rebuilt the trees In(w) and Out(w). + + // First, the edges of E' are removed from the decremental data structure. Next, + // for every w in S, the shortest-paths trees In(w) and Out(w) are built from + // scratch. + void remove(const T& u, const T& v) override; + + // 1. Let E <- E union Ev. + // 2. Let S <- S union {v}. + // 3. If |S| > t, then call init. + // 4. Otherwise, construct the trees In(v) and Out(v). + void insert(const T& u, const T& v) override; +}; + +template +void HenzingerKing::init() { + +} + +template +bool HenzingerKing::query(const T& u, const T& v) { + + return false; +} + +template +void HenzingerKing::remove(const T& u, const T& v) { + +} + +template +void HenzingerKing::insert(const T& u, const T& v) { + +} + +} // namespace algo + +#endif \ No newline at end of file diff --git a/algorithm/king.h b/algorithm/king.h new file mode 100644 index 0000000..6993558 --- /dev/null +++ b/algorithm/king.h @@ -0,0 +1,73 @@ +#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(u, v); + Out[w].remove(u, v); + } +} + +template +void King::insert(const T& u, const T& v) { + this->G.insert(u, v); + init(); +} + +} // namespace algo + +#endif \ No newline at end of file