Finding all the roots in a directed graph - algorithm

I need to find an algorithm for finding all the roots in a directed graph, in O(n+m).
I have an algorithm for finding a single root:
Run DFS(v) on some v in V. If the result is a single spanning tree, then v is a root. Otherwise, the result is a forest of trees. Then:
Run DFS(u) on the root of the last tree. If the result is a single spanning tree, then u is a root. Else, there are no roots in the graph.
Now if I want to find all the roots, is the best way to just run the above algorithm O(n) times, on a different vertex in the last tree every time ? Assuming I found a root, if another root exists then it must be on the last tree, then is it O(n+m) if I continue to run the above algorithm until receiving "no root exists" or until going over all vertices ?
Thanks in advance !

Two approaches:
Reverse the graph and calculate DFS-loop() and note the vertices which have no outgoing edges (like Abhishek said).
More efficient - Run DFS-loop() on the graph and keep track of vertices with no incoming edges using a true, false table.
Method 1 takes twice as long in the worst case.

First you should find all strongly connected components in graph. To build it in leaner time you can use Kosaraju's algorithm or Tarjan's algorithm. All root should be located in one such component. Next you find strongly connected components without incoming edges to it. If you have more then one such component, graph has no root vertices. In you has only one component, you should check that you can reach others component from it, in this case this components contains all root in graph.
Old variant.
You should calculate the number of incoming edges to vertex, this can be done in O(m). All vertices with zero number of incoming edges will be a root of the graph, for this you will need O(n) time.

Related

Algorithm to visit every node in a directed cyclic graph

As the title says, I have a graph that contains cycles and is directed. It's strongly connected so there's no danger of getting "stuck". Given a start node, I want to find the a path (ideally the shortest but that's not the thing I'm optimising for) that visits every node.
It's worth saying that many of the nodes in this graph are frequently connected both ways - i.e. it's almost undirected. I'm wondering if there's a modified DFS that might work well for this particular use case?
If not, should I be looking at the Held-Karp algortihm? The visit once and return to starting point restrictions don't apply for me.
The easiest approach would probably be to choose a root arbitrarily and compute a BFS tree on G (i.e., paths from the root to each other vertex) and a BFS tree on the transpose of G (i.e., paths from each other vertex to the root). Then for each other vertex you can navigate to and from the root by alternating tree paths. There are various quick optimizations to this method.
Another possibility would be to use A* on the search space consisting of states current node × set of visited nodes, with heuristic equal to the number of nodes not visited yet. The worst-case running time is comparable to Held–Karp (which you could also apply after running Floyd–Warshall to form a complete unsymmetric distance matrix).

How to traverse on only a cycle in a graph?

I'm attempting ch23 in CLRS on MSTs, here's a question:
Given a graph G and a minimum spanning tree T , suppose that we decrease the weight of one of the edges not in T . Give an algorithm for finding the minimum spanning tree in the modified graph.
A solution I found was to add this new changed edge in T, then exactly one simple cycle is created in T, traverse this cycle and delete the max-weight edge in this cycle, voila, the new updated MST is found!
My question is, how do I only traverse nodes on this simple-cycle? Since DFS/BFS traversals might go out of the cycle if I, say, start the traversal in T from one endpoint of this newly added edge in T.
One solution I could think of was to find the biconnected components in T after adding the new edge. Only one BCC will be found, which is this newly formed simple-cycle, then I can put in a special condition in my DFS code saying to only traverse edges/nodes in this BCC, and once a back-edge is found, stop the traversal.
Edit: graph G is connected and undirected btw
Your solution is basically good. To make it more formal you can use Tarjan's bridge-finding algorithm
This algorithm find the cut-edges (aka bridges) in the graph in linear time. Consider E' to be the cut-edges set. It is easy to prove that every edge in E' can not be on circle. So, E / E' are must be the cycle in the graph.
You can use hash-map or array build function to find the difference between your E and the cut-edges set
From here you can run simple for-loop to find the max weight edge which you want to remove.
Hope that help!

Dijkstra looped tree

Anyone knows this?
A looped tree is a weighted, directed graph built from a binary tree
by adding an edge from every leaf back to the root. Every edge has a
non-negative weight.
How much time would Dijkstra’s algorithm require to compute the shortest path between two vertices u and v in a looped tree with n
nodes?
Describe and analyze a faster algorithm.
How much time would Dijkstra’s algorithm require to compute the
shortest path between two vertices u and v in a looped tree with n
nodes?
It will take O(VlogV) time (worst case analysis).
Note that there is a single simple path for each pair of nodes (u,v) that connects u to v. If this path for some reason contains a very heavy weighted edge, Dijksta's algorithm is going to keep postponing taking this edge, and will fail to discover the correct route until it will, which will make the algorithm have to discover most of the vertices in the looped tree, making the complexity O(VlogV) (Note that E is in O(V) for this graph).
Describe and analyze a faster algorithm.
Since there is a single simple path, you just need to find it.
It can be easily done by finding the lowest common ancestor in the tree (without loops), and then finding a route to this ancestor from u.
Complexity of this algorithm is O(h) - where h is the height of the graph.
I think the answer by amit is wrong.
In Describing and analyze a faster algorithm.
you can't find the cheapest route from vertex u to this ancestor in O(h), therefore, this algorithm is not O(h). For 2 reasons, if internal nodes only have parent to child directed edge, we need to look down from u to find the cheapest route to common ancestor (or the root), and I am not aware of an algorithm that can do that. Second reason, if there are parent->child and child->parent edges, then the path from source vertex to lowest common ancestor vertex can be through any of the 3 adjacent vertex of any internal tree nodes( vertex) or 1 adjacent vertex(root) of any leaf node vertex, thus we can't do it in O(h).
Based on my understanding of the problem, child->parent edge is not in the definition of looped-tree graph. Therefore, the only we is to go down the tree and come back at the top and from root to target is a simple single path. Therefore, we reduce the problem to finding the cheapest route from u to root, thereby reduce the complexity.
Further, if target is a direct descendant of source, we will stop the during finding the cheapest route to root. if source is the root, the problem is trivial since the route is the simple single path from root to target by going down the subtrees of target.

How to detect if breaking an edge will make a graph disjoint?

I have a graph that starts off with a single, root node. Nodes are added one by one to the graph. At node creation time, they have to be linked either to the root node, or to another node, by a single edge. Edges can also be created and deleted (one by one, between any two nodes). Nodes can be deleted one at a time. Node and edge creation, deletion operations can happen in any arbitrary order.
OK, so here's my question: When an edge is deleted, is it possible do determine, in constant time (i.e. with an O(1) algorithm), if doing this will divide the graph into two disjoint subgraphs? If it will, then which side of the edge will the root node belong?
I'm willing to maintain, within reasonable limits, any additional data structure that can facilitate the derivation of this information.
Maybe it is not possible to do it in O(1), if so any pointers to literature will be appreciated.
Edit: The graph is a directed graph.
Edit 2: OK, maybe I can restrict the case to deletion of edges from the root node. [Edit 3: not, actually] Also, no edge lands into the root node.
To speed things up a little over the obvious O(|V|+|E|) solution, you could keep a spanning tree which is fairly easy to update as the graph is changed.
If an edge not in the spanning tree is deleted, then the graph isn't disconnected and do nothing. If an edge in the spanning tree is deleted, then you must try to find a new path between those two vertices (if you find one, use it to update the spanning tree, otherwise the graph is disconnected).
So, best case O(1), worst-case O(|V|+|E|), but fairly simple to implement anyway.
Is this a directed graph? The below assumes undirected.
What you are looking for is whether the given edge is a Bridge in the graph. I believe this can be found using a traversal looking for cycles containing that edge and would be O(|V| + |E|).
O(1) is too much to ask.
You might find that looking to maintain 2-edge connected components in dynamic graphs could be useful to you.
Eppstein et al have a paper on this: http://www.ics.uci.edu/~eppstein/pubs/EppGalIta-TR-93-20.pdf
which can maintain 2-edge connected components, in a graph of n nodes where edge insertions and deletions are allowed. It has O(sqrt(n)) time per update and O(log n) time per query.
So any time you delete, you can query in O(logn) to determine if the number of 2-edge connected components has changed. I suppose it can also tell you which component a specific node is in.
This paper is more general and applies to other graph problems, not only 2 edge connected components.
I suggest you look for bridges and dynamic 2-edge connectivity to get you started.
Hope that helps.
as said by Moron just before, you are actually looking for a Bridge in your graph.
Now a Bridge is an edge that has the described attribute and also originates and ends up in Cut Vertexes. Cut vertex is exactly what a Bridge is, but in a vertex (node) edition.
So the only way (though quite bending the initial data structure hypothesis) I can think of, to get a O(1) complexity for this, is if you first check every node in your graph if it is a Cut Vertex and then simply in constant time checking if the edge you want to delete is a attached to one of those two.
Finding if a node in a graph is a Cut Vertex takes O(m+n) where m = # edges and n= # nodes.
Cheers

How do I test whether a tree has a perfect matching in linear time?

Give a linear-time algorithm to test whether a tree has a perfect matching,
that is, a set of edges that touches each vertext of the tree exactly once.
This is from Algorithms by S. Dasgupta, and I just can't seem to nail this problem down. I know I need to use a greedy approach in some manner, but I just can't figure this out. Help?
Pseudocode is fine; once I have the idea, I can implement in any language trivially.
The algorithm has to be linear in anything. O( V + E ) is fine.
I think I have the solution. Since we know the graph is a tree, we know of the existance of leaf nodes, nodes with one edge and no children. In order for this node to be included in the perfect matching, that edge MUST exist in the final solution.
Ergo, we can find all edges connecting to a leaf node, add to the solution, and remove the touched edges from the graph. If, at the end of this process, we are left any remaining nodes untounched, there exists no perfect matching.
In the case of a "graph",
The first step of the problem should be to find the connected components.
Since every edge in the final answer connect two vertices, they belong to at most one of the connected components.
Then, the perfect matching could be found for each connected component.
Linear in what? Linear in the number of edges, keep the edges as an ordered incidence list, ie, every edge (vi, vj) in some total order. Then you can compare the two lists in O(n) of the edges.
The working algorithm would be something as follows:
For each leaf in the tree:
add edge from leaf to its parent to the solution
delete edge from leaf to its parent
delete all edges from the parent to any other vertices
delete leaf and parent from the tree
If the tree is empty then the answer is yes. Otherwise, there's no perfect matching.
I think that it's a simplified problem of finding a Hamiltonian path in a graph:
http://en.wikipedia.org/wiki/Hamiltonian_path
http://en.wikipedia.org/wiki/Hamiltonian_path_problem
I think that there are many solutions on the internet to this problem, but generally finding Hamilton cycle is a NP problem.

Resources