Add tests for same SCC O(1) query
This commit is contained in:
@@ -36,14 +36,14 @@ private:
|
|||||||
std::map<T, std::pair<Digraph<T>, Digraph<T>>> SPT;
|
std::map<T, std::pair<Digraph<T>, Digraph<T>>> SPT;
|
||||||
|
|
||||||
// Connect each representative with its SCC
|
// Connect each representative with its SCC
|
||||||
std::map<T, SCC<T>> SCCs;
|
std::map<T, SCC<T>> connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void DecrementalSCC<T>::init() {
|
void DecrementalSCC<T>::init() {
|
||||||
auto tarjan = Tarjan<T>(G).run();
|
auto SCCs = Tarjan<T>(G).findSCC();
|
||||||
|
|
||||||
for (auto& C : tarjan) {
|
for (auto& C : SCCs) {
|
||||||
const auto& w = C.representative();
|
const auto& w = C.representative();
|
||||||
|
|
||||||
// Create shortest-paths out-tree/in-tree
|
// Create shortest-paths out-tree/in-tree
|
||||||
@@ -55,7 +55,7 @@ void DecrementalSCC<T>::init() {
|
|||||||
A[v] = w;
|
A[v] = w;
|
||||||
|
|
||||||
// Link SCC with its representative w
|
// Link SCC with its representative w
|
||||||
SCCs[w] = C;
|
connection[w] = C;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ void DecrementalSCC<T>::remove(const T& u, const T& v) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Update In(w) and Out(w)
|
// Update In(w) and Out(w)
|
||||||
auto inTree = BFS<T>(SCCs[w]).run(w);
|
auto inTree = BFS<T>(connection[w]).run(w);
|
||||||
SPT[w] = std::make_pair(inTree, inTree.reverse());
|
SPT[w] = std::make_pair(inTree, inTree.reverse());
|
||||||
|
|
||||||
if (!SPT[w].second.vertices.contains(u) ||
|
if (!SPT[w].second.vertices.contains(u) ||
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public:
|
|||||||
Tarjan(Digraph<T> G) : G(G) {}
|
Tarjan(Digraph<T> G) : G(G) {}
|
||||||
|
|
||||||
//
|
//
|
||||||
std::vector<SCC<T>> run();
|
std::vector<SCC<T>> findSCC();
|
||||||
|
|
||||||
//
|
//
|
||||||
void strongConnect(const T& v);
|
void strongConnect(const T& v);
|
||||||
@@ -68,7 +68,7 @@ void Tarjan<T>::strongConnect(const T& v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
std::vector<SCC<T>> Tarjan<T>::run() {
|
std::vector<SCC<T>> Tarjan<T>::findSCC() {
|
||||||
for (const auto& v : G.vertices) {
|
for (const auto& v : G.vertices) {
|
||||||
if (p[v].index == -1) {
|
if (p[v].index == -1) {
|
||||||
strongConnect(v);
|
strongConnect(v);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ TEST_SUITE("Algorithm") {
|
|||||||
REQUIRE_EQ(G.vertices.size(), 9);
|
REQUIRE_EQ(G.vertices.size(), 9);
|
||||||
|
|
||||||
algo::Tarjan<std::uint16_t> tarjan(G);
|
algo::Tarjan<std::uint16_t> tarjan(G);
|
||||||
auto res = tarjan.run();
|
auto res = tarjan.findSCC();
|
||||||
|
|
||||||
std::vector<std::vector<std::uint16_t>> exp = {
|
std::vector<std::vector<std::uint16_t>> exp = {
|
||||||
{6, 8, 9},
|
{6, 8, 9},
|
||||||
@@ -63,7 +63,7 @@ TEST_SUITE("Algorithm") {
|
|||||||
REQUIRE_EQ(G.vertices.size(), 7);
|
REQUIRE_EQ(G.vertices.size(), 7);
|
||||||
|
|
||||||
algo::Tarjan<std::uint16_t> tarjan(G);
|
algo::Tarjan<std::uint16_t> tarjan(G);
|
||||||
auto res = tarjan.run();
|
auto res = tarjan.findSCC();
|
||||||
|
|
||||||
std::vector<std::vector<std::uint16_t>> exp = {
|
std::vector<std::vector<std::uint16_t>> exp = {
|
||||||
{2, 5, 7},
|
{2, 5, 7},
|
||||||
@@ -133,6 +133,18 @@ TEST_SUITE("Algorithm") {
|
|||||||
algo::DecrementalSCC<std::uint16_t> rz(G);
|
algo::DecrementalSCC<std::uint16_t> rz(G);
|
||||||
rz.init();
|
rz.init();
|
||||||
|
|
||||||
|
std::vector<std::vector<std::uint16_t>> exp = {
|
||||||
|
{2, 5, 7},
|
||||||
|
{1, 3, 4, 6}
|
||||||
|
};
|
||||||
|
|
||||||
|
CHECK_EQ(rz.query(1, 2), false);
|
||||||
|
CHECK_EQ(rz.query(1, 3), true);
|
||||||
|
CHECK_EQ(rz.query(1, 7), false);
|
||||||
|
CHECK_EQ(rz.query(2, 3), false);
|
||||||
|
CHECK_EQ(rz.query(2, 5), true);
|
||||||
|
CHECK_EQ(rz.query(5, 7), true);
|
||||||
|
|
||||||
//CHECK_EQ(rz.query(1, 2), true);
|
//CHECK_EQ(rz.query(1, 2), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ TEST_SUITE("Graph") {
|
|||||||
REQUIRE_EQ(G.vertices.size(), 9);
|
REQUIRE_EQ(G.vertices.size(), 9);
|
||||||
|
|
||||||
algo::Tarjan<std::uint16_t> tarjan(G);
|
algo::Tarjan<std::uint16_t> tarjan(G);
|
||||||
auto sccs = tarjan.run();
|
auto sccs = tarjan.findSCC();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("SCC T2") {
|
TEST_CASE("SCC T2") {
|
||||||
@@ -88,6 +88,6 @@ TEST_SUITE("Graph") {
|
|||||||
REQUIRE_EQ(G.vertices.size(), 7);
|
REQUIRE_EQ(G.vertices.size(), 7);
|
||||||
|
|
||||||
algo::Tarjan<std::uint16_t> tarjan(G);
|
algo::Tarjan<std::uint16_t> tarjan(G);
|
||||||
auto sccs = tarjan.run();
|
auto sccs = tarjan.findSCC();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user