Komponen Yang Sangat Terhubung

16

Dua simpul berbeda dalam grafik berarah sangat terhubung jika ada jalur dalam grafik dari satu sama lain. Sebuah komponen sangat terhubung dari grafik adalah bagian dari grafik sehingga setiap pasangan simpul yang berbeda dalam subset sangat terhubung, dan menambahkan lagi simpul untuk subset akan mematahkan properti ini.

Tantangan Anda adalah memisahkan grafik menjadi komponen-komponennya yang sangat terhubung. Khususnya, Anda harus menampilkan semua SCC dalam grafik.

I / O:

Sebagai input, Anda dapat menggunakan daftar tepi terarah, daftar adjacency, matriks adjacency, atau format input wajar lainnya. Tanyakan apakah Anda tidak yakin. Anda dapat mengasumsikan grafik tidak memiliki simpul yang benar-benar terputus, dan bahwa tidak ada tepi sendiri, tetapi Anda tidak dapat membuat asumsi lebih lanjut. Anda juga dapat secara opsional mengambil daftar simpul sebagai input, serta jumlah simpul.

Sebagai output, Anda harus memberikan partisi simpul, seperti daftar daftar simpul, di mana setiap sublist adalah komponen yang sangat terhubung, atau pelabelan simpul, di mana setiap label sesuai dengan komponen yang berbeda.

Jika Anda menggunakan pelabelan, label harus berupa simpul, atau urutan bilangan bulat berturut-turut. Ini untuk mencegah penghancuran komputasi ke dalam label.

Contoh:

Contoh-contoh ini mengambil daftar tepi, di mana setiap tepi diarahkan dari entri 1 ke entri kedua, dan partisi keluaran. Anda bebas menggunakan format ini atau yang lain.

Input ada di baris pertama, output ada di baris kedua.

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

Penilaian dan pembatasan:

Celah standar dilarang, seperti biasa. Juga, built-in yang khusus menangani komponen yang sangat terhubung dilarang.

Solusi harus berjalan dalam waktu tidak lebih dari satu jam pada contoh yang diberikan. (Ini dimaksudkan untuk mencegah solusi eksponensial lambat, dan tidak ada yang lain.)

Ini kode golf. Bytes paling sedikit menang.

isaacg
sumber
Seberapa fleksibel label yang kita tetapkan untuk komponen yang terhubung? Misalnya, apakah daftar indeks titik dalam komponen itu menjadi label yang valid?
xnor
@ xnor Sepenuhnya fleksibel. Harus cocok dengan pengujian kesetaraan / string identik.
isaacg
Bisakah format input grafik kami juga berisi jumlah simpul dan / atau daftar label simpul?
xnor
@xnata Ya untuk keduanya. Saya akan mengeditnya.
isaacg
Dalam test case terakhir, saya mendapatkan yang 8tidak ada dalam komponen dengan [3,4]karena tidak bisa hanya masing 6- masing dan 7tidak ada yang mencapai itu.
xnor

Jawaban:

7

Python 2 menggunakan numpy, 71 62 byte

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

Mengambil input sebagai numpymatriks yang mewakili kedekatan dan jumlah node. Menghasilkan output sebagai numpymatriks baris yang memberi label setiap simpul dengan nomor simpul terendah di komponennya.

Untuk matriks adjacency M, kekuatan matriks M**nmenghitung jumlah nlintasan -step dari setiap titik awal ke setiap titik ujung. Menambahkan identitas ke Mvia M+M**0memodifikasi matriks adjacency untuk menambahkan loop diri ke setiap sisi. Jadi, (M+M**0)**nhitung jalur panjang paling banyak n(dengan redundansi).

Karena setiap jalur memiliki panjang paling banyak n, jumlah node, di (i,j)mana titik jdapat dicapai dari isesuai dengan entri positif (M+M**0)**n. Matriks reachability kemudian R=(M+M**0)**n>0, di mana >0bekerja secara masuk akal.

Menghitung entrywise andsebagai R&R.T, di mana R.Tadalah transpos, kemudian memberikan matriks yang menunjukkan pasangan dari simpul yang dapat dicapai bersama. Ini ibaris th merupakan vektor indikator untuk simpul dalam komponen sangat terhubung sama seperti. Mengambil argmaxdari setiap barisnya memberikan indeks yang pertama Truedi dalamnya, yang merupakan indeks dari simpul terkecil dalam komponennya.

Tidak
sumber
4

JavaScript (ES6), 125 byte

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))

Mengambil daftar pasangan terarah sebagai argumen, sementara hasilnya adalah array untuk setiap simpul yang memberikan simpul pertama sangat terhubung, yang saya percaya dianggap sebagai pelabelan yang valid. Misalnya, dengan input [[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]]yang dikembalikan [, 1, 1, 3, 3, 1, 6, 6, 3](tidak ada titik 0; titik 1, 2 dan 5 memiliki label 1; 3, 4 dan 8 memiliki label 3 sedangkan 6 dan 7 memiliki label 6).

Neil
sumber
4

MATL , 26 22 byte

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

Ini menggunakan pendekatan yang sama dengan jawaban @ xnor .

Bekerja dalam versi bahasa saat ini (15.0.0) .

Input adalah matriks kedekatan dari grafik, dengan baris yang dipisahkan oleh titik koma. Kasus uji pertama dan terakhir adalah

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

Cobalah online!

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
Luis Mendo
sumber
3

Pyth, 13 byte

.gu+Gs@LQG.{k

Demonstrasi , Test suite

Input adalah daftar adjacency, direpresentasikan sebagai kamus yang memetakan simpul ke daftar simpul yang memiliki tepi (tetangga yang diarahkan). Output adalah partisi.

Inti dari program ini adalah kita menemukan kumpulan simpul yang dapat dijangkau dari masing-masing simpul, dan kemudian mengelompokkan simpul dengan set tersebut. Setiap dua simpul dalam SCC yang sama memiliki kumpulan simpul yang sama yang dapat dijangkau darinya, karena masing-masing simpul dapat dijangkau dari yang lain, dan keterjangkauan bersifat transitif. Setiap simpul dalam komponen yang berbeda memiliki set yang dapat dijangkau yang berbeda, karena masing-masing set tidak mengandung yang lain.

Penjelasan kode:

.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
isaacg
sumber