Make class Graph abstract and make derived classes Digraph and SCC

This commit is contained in:
stefiosif
2022-06-12 00:49:42 +03:00
parent b5b031db7f
commit 72741a6a5b
7 changed files with 113 additions and 113 deletions

View File

@@ -1,18 +1,18 @@
#ifndef BFS_H_
#define BFS_H_
#include "graph/graph.h"
using namespace graph;
#include "graph/digraph.h"
#include <algorithm>
#include <queue>
using namespace graph;
namespace algo {
template<typename T>
class BFS {
public:
BFS(Graph<T> G, T root) : G(G), root(root) {}
BFS(Digraph<T> G, T root) : G(G), root(root) {}
//
std::map<T, std::set<T>> run();
@@ -20,7 +20,7 @@ public:
//
std::map<T, bool> initExplore();
private:
Graph<T> G;
Digraph<T> G;
T root;
};

View File

@@ -1,23 +1,23 @@
#ifndef TARJAN_H_
#define TARJAN_H_
#include "graph/graph.h"
using namespace graph;
#include "graph/digraph.h"
#include "graph/scc.h"
#include <algorithm>
#include <iostream>
#include <ranges>
#include <stack>
#include <vector>
using namespace graph;
namespace algo {
template<typename T>
class Tarjan {
public:
Tarjan(Graph<T> G) : G(G) {}
Tarjan(Digraph<T> G) : G(G) {}
//
std::vector<std::vector<T>> run();
std::vector<SCC<T>> run();
//
void strongConnect(const T& v);
@@ -29,48 +29,48 @@ private:
bool onStack = false;
};
Graph<T> G;
Digraph<T> G;
std::stack<T> S;
std::int16_t index = 0;
std::map<T, Payload> vp;
std::vector<std::vector<T>> SCCs;
std::map<T, Payload> p;
std::vector<SCC<T>> SCCs;
};
template<typename T>
void Tarjan<T>::strongConnect(const T& v) {
vp[v].index = vp[v].lowlink = index++;
vp[v].onStack = true;
p[v].index = p[v].lowlink = index++;
p[v].onStack = true;
S.push(v);
for (const auto& w : G.adjMatrix[v]) {
if (vp[w].index == -1) {
if (p[w].index == -1) {
strongConnect(w);
vp[v].lowlink = std::min(vp[v].lowlink, vp[w].lowlink);
} else if (vp[w].onStack) {
vp[v].lowlink = std::min(vp[v].lowlink, vp[w].index);
p[v].lowlink = std::min(p[v].lowlink, p[w].lowlink);
} else if (p[w].onStack) {
p[v].lowlink = std::min(p[v].lowlink, p[w].index);
}
}
// If v is a root node, pop the stack and generate an SCC
if (vp[v].lowlink == vp[v].index) {
std::vector<T> SCC;
if (p[v].lowlink == p[v].index) {
//std::vector<T> scc;
std::map<T, std::set<T>> scc;
bool finished = false;
do {
const auto w = S.top();
S.pop();
vp[w].onStack = false;
SCC.push_back(w);
finished = vp[w].index == vp[v].index;
p[w].onStack = false;
scc[w] = G.adjMatrix[w];
finished = p[w].index == p[v].index;
} while (!finished);
SCCs.push_back(SCC);
SCCs.push_back(scc);
}
}
template<typename T>
std::vector<std::vector<T>> Tarjan<T>::run() {
std::vector<SCC<T>> Tarjan<T>::run() {
for (const auto& v : G.vertices) {
if (vp[v].index == -1) {
if (p[v].index == -1) {
strongConnect(v);
}
}