private IEnumerable <IDiGraph <T, TWeight> > StrongConnect(T vertex) { var metadata = _metadataLookup[vertex]; metadata.Index = _index; metadata.LowLink = _index; _index += 1; _stack.Push(vertex); metadata.OnStack = true; foreach (var outEdge in _graph.GetOutgoingEdges(vertex)) { var targetVertex = outEdge.TargetVertex; var outMetadata = _metadataLookup[targetVertex]; if (outMetadata.Index == -1) { foreach (var result in StrongConnect(targetVertex)) { yield return(result); } } if (outMetadata.OnStack) { metadata.LowLink = Math.Min(metadata.LowLink, outMetadata.LowLink); } } if (metadata.LowLink != metadata.Index) { yield break; } IDiGraph <T, TWeight> componentGraph = new DiGraph <T, TWeight>(_graph.DefaultEdgeWeight); T wVertex; do { wVertex = _stack.Pop(); var stackNodeMetadata = _metadataLookup[wVertex]; stackNodeMetadata.OnStack = false; componentGraph.AddVertex(wVertex); } while (!EqualityComparer <T> .Default.Equals(vertex, wVertex)); var filteredEdges = componentGraph.Vertices .SelectMany(v => _graph.GetOutgoingEdges(v)) .Where(e => componentGraph.Vertices.Contains(e.SourceVertex)) .Where(e => componentGraph.Vertices.Contains(e.TargetVertex)); foreach (var edge in filteredEdges) { componentGraph.AddEdge(edge.SourceVertex, edge.TargetVertex, edge.Weight); } yield return(componentGraph); }