Две разные вершины в ориентированном графе сильно связаны, если в графе есть путь от одного к другому. Сильно компонента связности графы является подмножеством графа таким образом, что каждая пара различных вершин в подгруппе сильно связана, и добавление каких - либо больше вершин к подмножеству бы нарушить это свойство.
Ваша задача состоит в том, чтобы разделить график на его сильно связанные компоненты. В частности, вы должны вывести все SCC на графике.
I / O:
В качестве входных данных вы можете использовать список направленных ребер, список смежности, матрицу смежности или любой другой приемлемый формат ввода. Спросите, если вы не уверены. Вы можете предположить, что граф не имеет полностью несвязных вершин и что нет собственных ребер, но вы не можете делать никаких дополнительных предположений. Вы также можете при желании принять список вершин в качестве входных данных, а также количество вершин.
В качестве выходных данных вы должны либо дать разбиение вершин, например, список списков вершин, где каждый подсписок является сильно связным компонентом, либо метку вершин, где каждая метка соответствует отдельному компоненту.
Если вы используете метки, метки должны быть либо вершинами, либо последовательной последовательностью целых чисел. Это сделано для того, чтобы избежать смещения вычислений в метки.
Примеры:
В этих примерах используются списки ребер, где каждое ребро направлено от 1-й записи ко второй записи, и выходные разделы. Вы можете использовать этот формат или другой.
Вход находится в первой строке, выход - во второй.
[[1, 2], [2, 3], [3, 1], [1, 4]]
[[1, 2, 3], [4]]
[[1, 2], [2, 3], [3, 4]]
[[1], [2], [3], [4]]
[[1, 2], [2, 1], [1, 3], [2, 4], [4, 2], [4, 3]]
[[1, 2, 4], [3]]
[[1, 2], [2, 3], [2, 5], [2, 6], [3, 4], [3, 7], [4, 3], [4, 8], [5, 1], [5, 6], [6, 7], [7, 6], [8, 7], [8, 4]]
[[1, 2, 5], [3, 4, 8], [6, 7]]
Подсчет очков и ограничения:
Стандартные лазейки , как всегда, запрещены. Кроме того, встроенные модули, которые специально работают с сильно связанными компонентами, запрещены.
Решения должны выполняться не более часа на предоставленных примерах. (Это предназначено для предотвращения медленных экспоненциальных решений и ничего больше.)
Это код гольф. Побеждает несколько байтов.
источник
8
не в компоненте,[3,4]
потому что он не может только каждый6
и7
(ни один из которых не достигает его).Ответы:
Python 2 с использованием numpy,
7162 байтаПринимает входные данные в виде
numpy
матрицы, представляющей смежность и количество узлов. Производит вывод в видеnumpy
матрицы строк, которая помечает каждую вершину наименьшим номером вершины в ее компоненте.Для матрицы смежности
M
мощность матрицыM**n
подсчитывает количествоn
-шаговых путей от каждой начальной вершины до каждой конечной вершины. Добавление идентификатора вM
viaM+M**0
изменяет матрицу смежности, добавляя цикл к каждому ребру. Таким образом,(M+M**0)**n
учитывается длина пути не болееn
(с избыточностью).Поскольку любой путь имеет длину не более
n
, число узлов, из(i,j)
которыхj
может быть достигнута вершина,i
соответствует положительной записи в(M+M**0)**n
. Матрица достижимости тогдаR=(M+M**0)**n>0
, где>0
работает входно.Вычисляя входное значение
and
какR&R.T
, гдеR.T
транспонирование, затем дает матрицу, указывающую пары взаимно достижимых вершин. Этаi
строка является вектором-индикатором для вершин в том же сильно связанном компоненте, что и он. Взятиеargmax
каждой строки дает индекс первойTrue
в нем, который является индексом самой маленькой вершины в ее компоненте.источник
JavaScript (ES6), 125 байт
Принимает список направленных пар в качестве аргумента, в то время как результатом является массив для каждой вершины, дающий первую вершину, тесно связанную с ней, которая, я считаю, считается допустимой маркировкой. Например, со входом, который
[[1, 2], [2, 3], [2, 5], [2, 6], [3, 4], [3, 7], [4, 3], [4, 8], [5, 1], [5, 6], [6, 7], [7, 6], [8, 7], [8, 4]]
он возвращает[, 1, 1, 3, 3, 1, 6, 6, 3]
(вершины 0 нет; вершины 1, 2 и 5 имеют метку 1; 3, 4 и 8 имеют метку 3, а 6 и 7 имеют метку 6).источник
MATL ,
2622 байтаЭто использует тот же подход, что и ответ @ xnor .
Работает в текущей версии (15.0.0) языка.
Входные данные - это матрица смежности графа, строки которой разделены точкой с запятой. Первый и последний контрольные примеры
Попробуйте онлайн!
источник
Pyth, 13 байт
Демонстрация , Тестовый пакет
Ввод - это список смежности, представленный в виде словаря, который отображает вершины в список вершин, к которым у него есть ребра (у его направленных соседей). Выход - это раздел.
Суть программы заключается в том, что мы находим набор вершин, которые достижимы из каждой вершины, а затем группируем вершины по этим наборам. Любые две вершины в одном и том же SCC имеют одинаковый набор вершин, достижимых из них, потому что каждая достижима из другой, и достижимость транзитивна. Любые вершины в разных компонентах имеют разные достижимые множества, потому что ни один из них не содержит другого.
Объяснение кода:
источник