Сильно підключені компоненти


16

Дві чіткі вершини в спрямованому графіку сильно пов'язані, якщо в графі є шлях один від одного. Сильно компонента зв'язності графи є підмножиною графа таким чином, що кожна пара різних вершин в підгрупі сильно пов'язана, і додавання будь - яких більше вершин до подмножеству б порушити це властивість.

Ваше завдання полягає в тому, щоб розділити графік на його сильно пов'язані компоненти. Зокрема, ви повинні вивести всі SCC на графіку.

I / O:

В якості введення можна використовувати список спрямованих країв, список суміжності, матрицю примикання або будь-який інший розумний формат введення. Запитайте, чи не впевнені ви. Ви можете припустити, що на графіку немає повністю відключених вершин і що немає власних країв, але ви не можете робити жодних подальших припущень. Ви також можете взяти список вершин як вхідні, а також кількість вершин.

Як вихід, ви повинні дати розподіл вершин, наприклад, список списків вершин, де кожен підпис є сильно з'єднаним компонентом, або маркування вершин, де кожна мітка відповідає іншому компоненту.

Якщо ви використовуєте маркування, мітки повинні бути або вершинами, або послідовною послідовністю цілих чисел. Це робиться для того, щоб запобігти зачистці обчислень на етикетках.

Приклади:

Ці приклади беруть списки ребер, де кожен край спрямований від першого запису до другого запису, і виводять розділи. Ви можете використовувати цей чи інший формат.

Вхід знаходиться на першому рядку, вихід - на другому рядку.

[[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]]

Оцінка та обмеження:

Стандартні лазівки , як завжди, заборонені. Також заборонені вбудовані модулі, які спеціально стосуються сильно з'єднаних компонентів.

На наведених прикладах рішення повинні працювати не більше години. (Це призначено для запобігання повільних експоненціальних рішень, і нічого іншого.)

Це код гольфу. Виграє найменше байт.


Наскільки гнучкими є мітки, які ми присвоюємо підключеному компоненту? Наприклад, чи буде список вершинних індексів у цьому компоненті дійсним міткою?
xnor

@xnor Повністю гнучка. Має відповідати тестуванню рівності / однакових рядків.
isaacg

Чи може наш формат введення графіку також містити кількість вершин та / або список міток вершин?
xnor

@xnor Так для обох. Я відредагую це.
isaacg

В останньому тестовому випадку я розумію, що 8це не в складі, [3,4]тому що це не може тільки кожен 6і7 (жоден з яких досягти цього).
xnor

Відповіді:


7

Python 2, використовуючи numpy, 71 62 байт

import numpy
def g(M,n):R=(M+M**0)**n>0;print(R&R.T).argmax(0)

Приймає введення як numpyматрицю, що представляє суміжність та кількість вузлів. Виводить вихід у вигляді numpyматриці рядків, яка мітить кожну вершину найнижчим числом вершин у її складовій.

Для матриці суміжності Mпотужність матриці M**nпідраховує кількість nпрохідних кроків від кожної стартової вершини до кожної кінцевої вершини. Додавання ідентичності до Mчерез M+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в ньому, який є індексом найменшої вершини в його складовій.


4

JavaScript (ES6), 125 байт

a=>a.map(([m,n])=>(e[m]|=1<<n|e[n],e.map((o,i)=>o&1<<m?e[i]|=e[m]:0)),e=[])&&e.map((m,i)=>e.findIndex((n,j)=>n&1<<i&&m&1<<j))

В якості аргументу береться список спрямованих пар, тоді як результат - це масив для кожної вершини, який дає першу вершину, сильно зв'язану з нею, що, на мою думку, вважається допустимим маркування. Наприклад, з введенням [[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).


4

MATL , 26 22 байт

tnX^Xy+HMY^gt!*Xu!"@f!

Для цього використовується той же підхід, що і у відповіді @ xnor .

Працює в поточній версії (15.0.0) мови.

Введення - матриця суміжності графіка, рядки розділені крапками з комою. Перший і останній тестові випадки є

[0 1 0 1; 0 0 1 0; 1 0 0 0; 0 0 0 0]

[0 1 0 0 0 0 0 0; 0 0 1 0 1 1 0 0; 0 0 0 1 0 0 1 0; 0 0 1 0 0 0 0 1; 1 0 0 0 0 1 0 0; 0 0 0 0 0 0 1 0; 0 0 0 0 0 1 0 0; 0 0 0 1 0 0 1 0]

Спробуйте в Інтернеті!

t     % implicitly input adjacency matrix. Duplicate
n     % number of elements
X^    % square root
Xy    % identity matrix of that size
+     % add to adjacency matrix
HM    % push size again
Y^    % matrix power
g     % convert to logical values (0 and 1)
t!*   % multiply element-wise by transpose matrix
Xu    % unique rows. Each row is a connected component
!     % transpose
"     % for each column
  @   %   push that column
  f!  %   indices of nonzero elements, as a row
      % end for each. Implicitly display stack contents

3

Pyth, 13 байт

.gu+Gs@LQG.{k

Демонстрація , тестовий набір

Введення - це список суміжності, представлений у вигляді словника, який відображає вершини до списку вершин, до якого він має ребра (спрямовані сусіди). Вихід - це розділ.

Суть програми полягає в тому, що ми знаходимо безліч вершин, до яких можна дістатися з кожної вершини, а потім групуємо вершини за цими множинами. Будь-які дві вершини в одному і тому ж SCC мають однаковий набір вершин, до яких можна дістатись, тому що кожна досяжна від інших, а доступність є перехідною. Будь-які вершини в різних компонентах мають різні досяжні множини, оскільки жоден набір не містить іншого.

Пояснення коду:

.gu+Gs@LQG.{k
                  Implicit: Q is the input adjacency list.
.g           Q    Group the vertices of Q by (Q is implicit at EOF)
  u       .{k     The fixed point of the following function, 
                  starting at the set containing just that vertex
   +G             Add to the set
     s            The concatenation of
      @LQG        Map each prior vertex to its directed neighbors
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.