Let A
be the adjacency matrix for the graph G = (V,E)
. A(i,j) = 1
if the nodes i
and j
are connected with an
This approach uses DFS, but is very efficient, because we don't repeat nodes in subsequent DFS's.
High-level approach:
Initialize the values of all the nodes to -1
.
Do a DFS from each unexplored node, setting that node's value to that of an auto-incremented value starting from 0
.
For these DFS's, update each node's value with previous node's value + i/n^k
where that node is the i
th child of the previous node and k
is the depth explored, skipping already explored nodes (except for checking for a bigger value).
So, an example for n = 10
:
0.1 0.11 0.111
j - k - p
0 / \ 0.12
i \ 0.2 l
m
1 1.1
q - o
...
You can also use i/branching factor+1
for each node to reduce the significant digits of the numbers, but that requires additional calculation to determine.
So above we did a DFS from i
, which had 2 children j
and m
. m
had no children, j
had 2 children, .... Then we finished with i
and started another DFS from the next unexplored node q
.
Whenever you encounter a bigger value, you know that a cycle occurred.
Complexity:
You check every node at most once, and at every node you do n checks, so complexity is O(n^2)
, which is the same as looking at every entry in the matrix once (which you can't do much better than).
Note:
I'll also just note that an adjacency list will probably be faster than an adjacency matrix unless it's a very dense graph.