#ifndef ITALIANO_H_ #define ITALIANO_H_ #include "algorithm/roditty_zwick.h" #include "algorithm/tarjan.h" #include "graph/breadth_first_tree.h" #include using namespace graph; namespace algo { template class Italiano : public RodittyZwick { public: Italiano(Digraph G) : G(G) {} void init(); bool query(const T& u, const T& v); void remove(const T& u, const T& v); private: Digraph G; // Transitive closure matrix, used to answer reachability queries in O(1) std::map> TC; // Each vertex's reachability tree std::map> RT; // Incoming / Outgoing edges struct Edges { std::forward_list inc; std::forward_list out; }; std::map E; }; template void Italiano::init() { for (const auto& u : std::views::keys(G.adjMatrix)) { for (const auto& v : G.adjMatrix[u]) { E[v].inc.push_front(u); E[u].out.push_front(v); TC[u][v] = false; } RT[u] = BreadthFirstTree(G, u); TC[u][u] = true; for (const auto& v : std::views::keys(RT[u].adjMatrix)) { TC[u][v] = true; } } } template bool Italiano::query(const T& u, const T& v) { return TC[u][v]; } template void Italiano::remove(const T& u, const T& v) { std::map> R; for (const auto& w : std::views::keys(G.adjMatrix)) { if (RT[w].contains(u, v)) { R[w].insert(v); } E[u].inc.remove(v); E[u].out.remove(u); G.remove(u, v); } //for (const auto& w : std::views::keys(G.adjMatrix)) { // while (R[w].size() > 0) { // auto pop = R[w]. // } //} } } // namespace algo #endif