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 ith 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.