class Digraph
{
private:
int V;
int E;
int* adj;
public:
Digraph(int V);
int V() { return V; }
int E() { return E; }
void addEdge(int v, int w);
int& adj(int v) { return adj[v]; }
Digraph reverse();
String toString();
}
Digraph::Digraph(int v)
{
V = v;
E = 0;
adj = new int[v];
for (int i = 0; i < V; ++i)
{
adj[i] = new int[V - 1];
adj[i] = 0;
}
}
void Digraph::addEdge(int v, int w)
{
adj[v].add(w);
E++;
}
Digraph::reverse()
{
Digraph R = new Digraph(V);
for (int v = 0; v < V; ++v)
for (int w : adj(v))
R.addEdge(w, v);
return R;
}
class DirectedCycle
{
private:
bool* marked;
int* edgeTo;
stack<int> cycle;
bool* onStack;
void dfs(Digraph G, int v)
{
onStack[v] = true;
marked[v] = true;
for (int w : G.adj(v))
{
if (hasCycle()) return;
else if(!marked[w])
{
edgeTo[w] = v;
dfs(G, w);
}
else if (onStack[w])
{
for (int x = v; x != w; x = edgeTo[x])
cycle.push(x);
cycle.psuh(w);
cycle.push(v);
}
}
onStack[v] = false;
}
public:
DirectedCycle(Digraph G)
{
onStack = new bool[G.V()];
marked = new bool[G.V()];
edgeTo = new int[G.V()];
for (int v = 0; v < G.V(); ++v)
if (!marked[v]) dfs(G, v);
}
bool hasCycle() { return !cycle.empty(); }
stack<int> cycle() { return cycle; }
}
class DepthFirstOrder
{
private:
bool* marked[];
queue<int> pre;
queue<int> post;
stack<int> reversePost;
void dfs(Digraph G, int v)
{
pre.push(v);
marked[v] = true;
for (int w : v.adj())
if (!marked[v]) dfs(G, w);
post.push(v);
reversePost.push(v);
}
public:
DepthFirstOrder(Digraph G)
{
marked = new bool[G.V()];
for (int v = 0; v < G.V(); ++v)
if (!marked[v]) dfs(G, v);
}
}