Zuerst machen Sie ein DFS auf dem Graph, beginnend mit dem Quellknoten, der, wie Sie sagen, im Voraus bekannt ist. Wenn Sie auf eine Back Edge [1] stoßen, haben Sie einen Zyklus und Sie können mit einem Fehler beenden.Während dieser Durchquerung können Sie feststellen, ob Knoten vorhanden sind, die nicht von der Quelle [2] aus erreichbar sind, und die entsprechenden Maßnahmen ergreifen.
Sobald Sie die grafische Darstellung festgestellt haben, ein DAG ist, kann sichergestellt werden, dass jeder Knoten auf einem Pfad durch einen anderen DFS von der Quelle zur Senke liegt, von der Quelle ausgehend, wie folgt:
bool have_path(source, sink) {
if source == sink {
source.flag = true
return true
}
// traverse all successor nodes of `source`
for dst in succ(source) {
if not dst.flag and not have_path(dst, sink)
return false // exit as soon as we find a node with no path to `sink`
}
source.flag = true;
return true
}
The Prozedur have_path
legt einen booleschen flag
in jedem Knoten fest, für den ein Pfad von diesem Knoten zu der Senke existiert. Zur gleichen Zeit durchläuft die Prozedur nur Knoten, die von der Quelle erreichbar sind, und sie durchquert alle Knoten, die von der Quelle erreichbar sind. Wenn die Prozedur wahr zurückgibt, dann liegen alle Knoten, die von der Quelle erreichbar sind, auf einem Pfad zu der Senke. Nicht erreichbare Knoten wurden bereits in der ersten Phase behandelt.
[1] eine Kante, einen Knoten mit einer größeren DFS-Nummer zu einem Knoten mit einer geringeren DFS Nummer verknüpft, dass nicht bereits vollständig abgearbeitet, also noch immer auf der DFS-Stack
[2 ] z.B sie hätten keine zugewiesene DFS-Nummer
Finden Sie die stark verbundenen Komponenten. Dann haben Sie die Quelle CC und Senke CC. Überprüfen Sie, ob beide nur ein Element enthalten. Die Komplexität ist ebenfalls linear. –
Eigentlich ist Tarjans Algorithmus derjenige, der stark verbundene Komponenten findet? –