#ifndef ITALIANO_H_ #define ITALIANO_H_ #include "algorithm/roditty_zwick.h" #include "algorithm/tarjan.h" #include "tree/breadth_first_tree.h" #include using namespace graph; using namespace tree; 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; // Connect each vertex with its representative SCC std::map> TC; // Reachability trees std::map> RT; // Incoming / Outgoing edges struct Edges { std::forward_list Ein; std::forward_list Eout; }; std::map, Edges> E; }; template void Italiano::init() { } template bool Italiano::query(const T& u, const T& v) { return TC[u] == TC[v]; } template void Italiano::remove(const T& u, const T& v) { for (const auto& w : G.adjMatrix) { // Check if (u,v) edge of T(w) || p(w,v) points to (u,v) // If yes => set p(w, v) to point to the next edge (u',v) in Ein(v) // If (u,v) the last edge, then set it to point to null // If T(w) contains u' then the new edge reconnects v to T(w) // As this needs to be checked, we set R(w) <- {v} // If (u,v) is not edge of T(w) or is the last edge in Ein(v), R(w) <- phi // Remove (u,v) from Eout(u) and Ein(v) } for (const auto& w : G.adjMatrix) { // Check tentative pointers of the vertices in R(w). // While there is a vertex x in R(w), scan the edges in Ein(x), starting // from the edge pointed to by p(w,x), until an edge (u',x) for which // p(w,u') != null is found or Ein(x) is exhausted. // If such edge is found, x is removed from R(w). // If the list is exhausted, set p(w,x) to null and M(w,x) to 0 // Then scan all Eout(x). If (x,x') is tree edge, add x' to R(w) } } } // namespace algo #endif