Zwei verschiedene Eckpunkte in einem gerichteten Graphen sind stark verbunden, wenn der Graphen einen Pfad von einem zum anderen aufweist. Eine stark verbundene Komponente des Diagramms ist eine Teilmenge des Diagramms, sodass jedes Paar unterschiedlicher Scheitelpunkte in der Teilmenge stark verbunden ist, und das Hinzufügen weiterer Scheitelpunkte zur Teilmenge würde diese Eigenschaft aufheben.
Ihre Herausforderung besteht darin, ein Diagramm in seine eng miteinander verbundenen Komponenten zu unterteilen. Insbesondere müssen Sie alle SCCs im Diagramm ausgeben.
I / O:
Als Eingabe können Sie eine Liste gerichteter Kanten, eine Adjazenzliste, eine Adjazenzmatrix oder ein anderes angemessenes Eingabeformat verwenden. Fragen Sie, ob Sie sich nicht sicher sind. Sie können davon ausgehen, dass das Diagramm keine vollständig getrennten Scheitelpunkte hat und dass es keine Selbstkanten gibt, aber Sie können möglicherweise keine weiteren Annahmen treffen. Optional können Sie auch die Liste der Scheitelpunkte als Eingabe sowie die Anzahl der Scheitelpunkte verwenden.
Als Ausgabe müssen Sie entweder eine Partitionierung der Scheitelpunkte angeben, z. B. eine Liste von Scheitelpunktlisten, bei der jede Unterliste eine stark verbundene Komponente ist, oder eine Beschriftung von Scheitelpunkten, bei der jede Beschriftung einer anderen Komponente entspricht.
Wenn Sie eine Beschriftung verwenden, müssen die Beschriftungen entweder Eckpunkte oder eine aufeinanderfolgende Folge von ganzen Zahlen sein. Dies soll verhindern, dass die Berechnung in die Etiketten verschoben wird.
Beispiele:
In diesen Beispielen werden Kantenlisten erstellt, in denen jede Kante vom ersten zum zweiten Eintrag geleitet wird, und Partitionen ausgegeben. Sie können dieses oder ein anderes Format verwenden.
Der Eingang befindet sich in der ersten Zeile, der Ausgang in der zweiten Zeile.
[[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]]
Wertung und Einschränkungen:
Standardlücken sind wie immer verboten. Außerdem sind eingebaute Komponenten, die sich speziell mit stark verbundenen Komponenten befassen, verboten.
Die Lösungen sollten nach den angegebenen Beispielen nicht länger als eine Stunde dauern. (Dies soll langsame exponentielle Lösungen und nichts anderes verhindern.)
Das ist Code Golf. Wenigste Bytes gewinnt.
quelle
8
nicht in einer Komponente enthalten ist,[3,4]
da es nicht nur jeder kann6
und7
(keiner von beiden kann es erreichen).Antworten:
Python 2 mit Numpy,
7162 BytesNimmt die Eingabe als
numpy
Matrix, die die Nachbarschaft und die Anzahl der Knoten darstellt. Erzeugt die Ausgabe alsnumpy
Zeilenmatrix, die jeden Scheitelpunkt mit der niedrigsten Scheitelpunktnummer in seiner Komponente beschriftet.Für eine Adjazenzmatrix
M
, die Matrix - LeistungsM**n
zählt die Anzahl dern
-Schritt Pfade von jedem Anfangsknoten zu jedem Endknoten. Durch Hinzufügen der Identität zuM
via wirdM+M**0
die Adjazenzmatrix so geändert, dass jeder Kante eine Selbstschleife hinzugefügt wird. So(M+M**0)**n
zählt Wege der Länge höchstensn
(mit Redundanz).Da jeder Pfad höchstens eine Länge hat
n
, entspricht die Anzahl der Knoten, von(i,j)
denen aus jeder Scheitelpunkt erreicht werdenj
kanni
, einem positiven Eintrag von(M+M**0)**n
. Die Erreichbarkeitsmatrix ist dannR=(M+M**0)**n>0
, wo das>0
eingangsseitig funktioniert.Berechnet man den eingangsweisen Wert
and
alsR&R.T
, woR.T
sich die Transponierte befindet, so erhält man eine Matrix, die die Paare der miteinander erreichbaren Eckpunkte angibt. Diei
dritte Zeile ist ein Indikatorvektor für Scheitelpunkte in derselben stark verbundenen Komponente wie sie. Ausargmax
jeder Zeile wird der Index der erstenTrue
in der Zeile genommen , der der Index des kleinsten Scheitelpunkts in seiner Komponente ist.quelle
JavaScript (ES6), 125 Byte
Nimmt eine Liste gerichteter Paare als Argument, während das Ergebnis ein Array für jeden Scheitelpunkt ist, das den ersten Scheitelpunkt angibt, der eng damit verbunden ist, was meiner Meinung nach als gültige Bezeichnung gilt. Beispiel: Bei der Eingabe
[[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]]
, die zurückgegeben wird[, 1, 1, 3, 3, 1, 6, 6, 3]
(es gibt keinen Scheitelpunkt 0; Scheitelpunkte 1, 2 und 5 haben die Bezeichnung 1; 3, 4 und 8 haben die Bezeichnung 3, während 6 und 7 die Bezeichnung 6 haben).quelle
MATL ,
2622 BytesDies verwendet den gleichen Ansatz wie die Antwort von @ xnor .
Funktioniert in der aktuellen Version (15.0.0) der Sprache.
Die Eingabe ist die Adjazenzmatrix des Diagramms mit durch Semikolons getrennten Zeilen. Der erste und der letzte Testfall sind
Probieren Sie es online!
quelle
Pyth, 13 Bytes
Vorführung , Testsuite
Die Eingabe ist eine Adjazenzliste, die als Wörterbuch dargestellt wird und Scheitelpunkte der Liste von Scheitelpunkten zuordnet, zu denen sie Kanten hat (ihre gerichteten Nachbarn). Ausgabe ist eine Partition.
Die Essenz des Programms besteht darin, dass wir die Menge der Scheitelpunkte finden, die von jedem Scheitelpunkt aus erreichbar sind, und dann die Scheitelpunkte nach diesen Mengen gruppieren. Zwei beliebige Scheitelpunkte in derselben SCC haben denselben Satz von Scheitelpunkten, die von ihnen aus erreichbar sind, da jeder von dem anderen aus erreichbar ist und die Erreichbarkeit transitiv ist. Alle Scheitelpunkte in verschiedenen Komponenten haben unterschiedliche erreichbare Mengen, da keine der beiden Mengen die andere enthält.
Code Erklärung:
quelle