Is there an efficient algorithm to enumerate all the cycles within the Strongly Connected Component of a directed graph?
-
What is the most efficient algorithm to decompose a Strongly Connected Component of a directed graph into ALL of the constituent cycles? I solved this in a brute-force manner (Do DFS within the SCC from "every" vertex, find cycles by detecting back-edges incident on the start vertex and at the end remove all duplicate cycles). [Example] Consider this 4-vertex directed graph represented by the adj-list, a --> {b, d} b --> {c, d} c --> {a} d --> {a, c} The 5 output cycles should be, {a, b, c}, {a, b, d}, {a, d}, {a, d, c}, {a, b, d, c}
-
Answer:
D. B. Johnson, "Finding All the Elementary Circuits of a Directed Graph," SIAM Journal of Computing, 4(1), 1975 pp. 77â84.http://dutta.csc.ncsu.edu/csc791_spring07/wrap/circuits_johnson.pdf. C++ demo /* [Input SCC format] vertex indices start from 0 --- N = number of nodes in the SCC v1 OutDeg(v1) <indices of the vertices adj to v1> v2 OutDeg(v2) <indices of the vertices adj to v2> ... vN OutDeg(vN) <indices of the vertices adj to vN> ---- e.g for 3-vertex complete directed graph the input is 3 0 2 1 2 1 2 0 2 2 2 0 1 [Usage] ./a.out < input.txt */ #include <algorithm> #include <iostream> #include <vector> #include <list> using namespace std; typedef vector< list<size_t> > AdjListT; AdjListT A, B; vector<size_t> node_stack; vector<size_t> blocked; size_t s; void UNBLOCK(size_t); bool CIRCUIT(size_t); void OutputCycle(vector<size_t>&); int main(void) { size_t N, copy_of_N; cin >> N; copy_of_N = N; A.resize(N); blocked.resize(N); B.resize(N); while (N--) { size_t u, v, out_degree; cin >> u >> out_degree; while (out_degree--) { cin >> v; A.at(u).push_back(v); } } N = copy_of_N; for (size_t i = 0; i < N; ++i) blocked[i] = false; s = 0; while (s < N) { CIRCUIT(s); A[s].clear(); for (size_t i = 0; i < N; ++i) A[i].remove(s); for (size_t i = 0; i < N; ++i) { blocked[i] = false; B[i].clear(); } ++s; } return 0; } bool CIRCUIT(size_t v) { bool f = false; node_stack.push_back(v); blocked[v] = true; for (list<size_t>::iterator iw = A[v].begin(); iw != A[v].end(); ++iw) { size_t w = *iw; if (w == s) { OutputCycle(node_stack); f = true; } else if (!blocked[w]) { if (CIRCUIT(w)) f = true; } } if (f) UNBLOCK(v); else for (list<size_t>::iterator iw = A[v].begin(); iw != A[v].end(); ++iw) { size_t w = *iw; if (find(B[w].begin(), B[w].end(), v) == B[w].end()) B[w].push_back(v); } node_stack.pop_back(); return f; } void UNBLOCK(size_t u) { blocked[u] = false; for (list<size_t>::iterator iw = B[u].begin(); iw != B[u].end();) { size_t w = *iw; iw = B[u].erase(iw); if (blocked[w]) UNBLOCK(w); } return; } void OutputCycle(vector<size_t>& node_stack) { for (vector<size_t>::iterator i = node_stack.begin(); i != node_stack.end(); ++i) cout << *i << " "; cout << endl; return; }
Abhijeet N. Vaidya at Quora Visit the source
Related Q & A:
- how to process a simple loop in WWW::Mechanize to be more efficient?Best solution by stackoverflow.com
- How To Use the Graph API to Upload Photos to a user’s profile?Best solution by Stack Overflow
- How to find connected components of a random graph?Best solution by Mathematics
- Is the Google's PageRank algorithm a secret?Best solution by Theoretical Computer Science
- How to graph a quadratic function on a graphing calculator?Best solution by ChaCha
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.