4

I am searching for an algorithm for finding every weakly connected component in a directed graph. I know for an undirected graph you can do this via a dfs but this obviously doenst work for an directed graph. I am saving my graph as an adjacents list. For example:

A -> B
B -> C
D -> X

So A-B-C is a connected component an D-X

I am not searching for an algorithm for finding strongly connected components!!

Exagon
  • 4,798
  • 6
  • 25
  • 53
  • 1
    Well, you should precise that are you meaning then you are talking about connected components in directed graph. Do you mean connected components in "undirected way"? – mingaleg Mar 18 '16 at 18:22
  • 1
    As far as I know a directed graph doesn't have a connected component, you can talk about weakly connected components (for which you just use dfs + turn the graph undirected) and strongly connected components. Can you define better what you mean by connected component of a directed graph? – questing Mar 18 '16 at 18:25
  • Ok, just make all the edges undirected and than find the components – mingaleg Mar 18 '16 at 18:28
  • what do you mean by "connected". "connected components" don't exist in directed graphs. Only "strongly connected components" and "weak connected components". In it's current state this question should be closed as "unclear what you're asking". –  Mar 18 '16 at 18:38

2 Answers2

3

Unless your memory constraints are too strict, you can keep a second, temporary adjacency list. In that second adjacency list you put each edge a->b and you also put edges in reverse direction. (i.e. b->a) Then, you can use DFS on that adjacency list to find connected components.

ilim
  • 4,477
  • 7
  • 27
  • 46
  • 1
    simply storing the reverse to each edge should actually do, reducing the space required. –  Mar 18 '16 at 18:41
  • I figured it would be easier to conceptualize turning the directed graph into an undirected one. After all the space complexity is the same. You are obviously correct, though. It halves the required space to not store the edges of the original graph twice. – ilim Mar 18 '16 at 18:52
2

A pretty simple solution would be as follows:
Start by creating an undirected graph from the given graph - simply make a copy and add the reverse for each edge to the set of edges. Create a copy of the set of vertices, start with an arbitrary vertex and DFS-traverse the component containing the vertex, removing all traversed nodes from the set and adding them to a list. Repeat this until the list is empty.

In pseudocode:

bimap edges
edges.putAll(graph.edges())

set vertices = graph.vertices()

list result

while !vertices.isEmpty()
    list component

    vertex a = vertices.removeAny()
    dfsTraverse(a , v -> {
        vertices.remove(v)
        component.add(v)
    })

    result.add(component)