Reputation: 31
Given an array of node and an array of edges, how do you calculate the number of connected graphs?
Upvotes: 3
Views: 3124
Reputation: 3093
For undirected graphs, this can be done in O(n) time, with a simple DFS. Here's how:
Define explore
as a procedure that finds all the nodes that can be reached from a given node. This is just a recursive DFS-like procedure where at each node, you find all the children of that node and push them onto the stack.
To find the answer, start the DFS at any node and initiate the explore
procedure on that node. Keep an integer(lets say cc
) and pass it to the explore
procedure every time it is called. Also, keep a hashmap/dictionary or such that maps cc
to the corresponding node. At each level of the explore
procedure, map the current node to cc
at the moment. Every time the explore procedure is called recursively, pass it the same value of cc
.
Every time explore
returns to the DFS loop, increment cc
and pass that value the next time. Once you are done with the entire DFS, you will have a dictionary that maps each node to it's corresponding connected component number. The value of cc
at the end of this procedure can give you the number of connected components there are in the graph.
Here's the pseudo-code:
function explore(node, graph, cc, map){
map(currentNode) = cc
//find all children of current node, and push onto stack.
//mark current node as visited
for i in stack:
explore(i, graph, cc, map)
}
function DFS{
int cc = -1
for node in keysOfGraph:
if not visited:
cc++
explore(node, graph, cc, map)
return cc
}
From Dasgupta Algorithms (section 3.2.3)
Upvotes: 0
Reputation: 30235
To elaborate on quasiverse's answer, here's a short pseudo code for it:
make_set(v) creates a new set whose only member is v.
union(x, y) unites the two sets x and y. The representative element for the new set is chosen from one of the two sets
get_representatve(v) returns the representative of the set the given node is a member of.
Find connected components in a graph G = (V, E):
foreach vertex v in V:
make_set(v)
foreach edge (u, v) in E:
if get_representatve(u) != get_representatve:
union(u, v)
Implementing the necessary functions is an exercise for the reader ;-) Anyway it'll work fine for undirected graphs, but if you want strongly connected components you should look at Tarjan's algorithm.
For parallel implementations there exists afaik no work-efficient deterministic algorithm, but some interesting random ones.
Upvotes: 1
Reputation: 8250
Upvotes: 1
Reputation: 7272
You can use a union find (you can search it up). Start with all of the nodes as separate sets, then for each edge join the two nodes that the edge connects into the same set. Then check how many different sets there are by going through all the nodes and finding how many different representatives there are.
Upvotes: 1
Reputation: 6021
Yes, there is an algorithm which is linear in the size of the graph, O(|V| + |E|).
visited := the empty set
count := 0
for each vertex v in vertices:
if v not in visited:
count++
add v and all nodes reachable from v to visited
return count
Upvotes: 0