Skip to content

Instantly share code, notes, and snippets.

@MaskRay
Last active December 29, 2024 02:12
Show Gist options
  • Save MaskRay/3a66d4faf01bf78a3067a6f5f229200b to your computer and use it in GitHub Desktop.
Save MaskRay/3a66d4faf01bf78a3067a6f5f229200b to your computer and use it in GitHub Desktop.
Johnson's algorithm - Finding All the Elementary Circuits of a Directed Graph
#include <algorithm>
#include <cstdio>
#include <type_traits>
#include <vector>
using namespace std;
#define ALL(x) (x).begin(), (x).end()
#define FOR(i, a, b) for (remove_cv<remove_reference<decltype(b)>::type>::type i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
int ri() {
int x;
scanf("%d", &x);
return x;
}
vector<int> vis;
vector<char> blocked;
vector<vector<int>> es, closed;
void unblock(int u) {
blocked[u] = false;
for (int v: closed[u])
if (blocked[v])
unblock(v);
}
bool johnson_cycle(int u, int src) {
bool found = false;
vis.push_back(u);
blocked[u] = true;
for (int v : es[u])
if (v == src) {
for (int w: vis)
printf("%d ", w);
puts("");
found = true;
} else if (!blocked[v])
found |= johnson_cycle(v, src);
if (found)
unblock(u);
else
for (int v: es[u])
if (v >= src) {
auto &c = closed[u];
if (find(ALL(c), v) == c.end())
c.push_back(v);
}
vis.pop_back();
return found;
}
int main() {
int n = ri(), v;
es.resize(n);
REP(i, n)
for (int k = ri(); k--; )
es[i].push_back(ri());
blocked.resize(n);
closed.resize(n);
REP(i, n) {
fill(blocked.begin()+i, blocked.end(), false);
johnson_cycle(i, i);
blocked[i] = true;
}
}
/*
(0,1) (0,2) (1,0) (1,2) (2,0) (2,3) (3,1)
input:
4
2 1 2
2 0 2
2 0 3
1 1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment