I was asked for my homework to write an efficient algorithm that finds all the vertices in a directed graph which have even length of path to them from the given vertex.
This is what I thought of:
(It's very similar to "Visit" algorithm of DFS)
Visit(vertex u)
color[u]<-gray
for each v E adj[u]
for each w E adj[v]
if color[w] = white then
print w
Visit(w)
I think it works but I'm having hard time calculating it's efficiency, especially when the graph is with cycles. Could you help me?
If I may suggest an alternative - I would have reduced the problem and use DFS instead of modifying DFS.
Given a graph G = (V,E)
, cretae a graph G' = (V,E')
where E'={(u,v) | there is w in V such that (u,w) and (w,v) are in E)
In other words - we are creating a graph G', which has edge (u,v) if and only if there is a path of length 2 from u to v.
Given that graph, we can derive the following algorithm [high level pseudo-code]:
s
, and mark the same nodes DFS marked.Correctness and time complexity analysis of the solution:
Complexity:
The complexity is obviously O(min{|V|^2,|E|^2} + |V|)
, because of part 1 - since there are at most min{|E|^2,|V|^2}
edges in G', so DFS on step 2 runs in O(|E'| + |V|) = O(min{|V|^2,|E|^2} + |V|)
Correctness:
If the algorithm found that there is a path from v0 to vk, then from the correctness of DFS - there is a path v0->v1->...->vk on G', so there is a path v0->v0'->v1->v1'->...->vk
of even length on G.
If there is a path of even length on G
from v0
to vk
, let it be v0->v1->...->vk
. then v0->v2->...->vk
is a path on G'
, and will be found by DFS - from the correctness of DFS.
As a side note:
Reducing problems instead of modifying algorithms is usually less vulnurable to bugs, and easier to analyze and prove correctness on, so you should usually prefer these over modifying algorithms when possible.
EDIT: regarding your solution: Well, analysing it shows they are both pretty much identical - with the exception of I was generating E'
as pre-processing, and you are generating it on the fly, in each iteration.
Since your solution is generating the edges on the fly - it might to doing some work more then once. However, it is bounded to the job at most |V|
times more, since each vertex is being visited at most once.
Assuming |E| = O(|V|^2)
for simplicity, giving us total an upper bound for the run time of O(|V|^3)
for your solution.
It is also a lower bound, look at the example of a clique, During each visit()
of any node, the algorithm will do O(|V|^2)
to generate all possibilities, and visit()
one of the possibilities, since we visit exactly |V|
nodes, we get total run time of Omega(|V|^3)
Since we found the solution is both O(|V|^3)
and Omega(|V|^3)
, it is total of Theta(O(|V|^3))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With