Вы можете легко изменить Алгоритм Флойд-Варшалла . (Если вы совсем не знакомы с теорией графов, я предлагаю проверить ее, например, получить копию Введение в алгоритмы ).
Традиционно вы запускаете path[i][i] = 0
для каждого i
. Но вместо этого вы можете начать с path[i][i] = INFINITY
. Это не повлияет на сам алгоритм, так как эти нули в любом случае не использовались в вычислениях (поскольку путь path[i][j]
никогда не изменится для k == i
или k == j
).
В конце, path[i][i]
- это длина кратчайшего цикла, проходящего через i
. Следовательно, вам нужно найти min(path[i][i])
для всех i
. И если вам нужен сам цикл (не только его длина), вы можете сделать это так же, как это обычно делается с обычными путями: запоминая k
во время выполнения алгоритма.
Кроме того, вы также можете использовать алгоритм Дейкстры , чтобы найти кратчайший цикл, проходящий через любой данный узел. Если вы запустите эту модифицированную Dijkstra для каждого узла, вы получите тот же результат, что и с Floyd-Warshall. А поскольку у каждого Дейкстры есть O(n^2)
, вы получите одинаковую O(n^3)
общую сложность.