Dijkstra looped tree - algorithm

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.

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).

Vertex cover for tree greedy approach

Question: Let T be an n-node tree rooted at some node r. We want to place as few guards as
possible on nodes of T, such that every edge of T is guarded: an edge between a parent
node v and its child w is guarded if one places a guard on at least one of these two nodes
v, w.
Give an O(n) time algorithm for finding an optimal solution to the problem.
My approach was to do post order traversal from the root and place a guard on a node that is part of an unguarded edge except if that node is a leaf...but this algorithm wouldn't work if all the nodes were arranged in a linear chain because my algorithm would place guards on every node except for the ends of the chain.
I've looked online and checked out the DP solutions, which make sense to me but I was wondering if there's a greedy algorithm to find a vertex cover for a tree

How can we construct an algorithm in O(V +E) to compute a path that traverses each edge of G exactly once in each direction

Consider connected graph G that is not directed.How can we construct an algorithm in O(V +E) to compute a path that traverses each edge of G exactly once in each direction
A path with that property is called an Eulerian path. There's a theorem that says a path like this exists if and only if every node has even degree or there are exactly two nodes of odd degree.
There are many algorithms for constructing Eulerian paths in linear time. The general idea is (usually) to walk around the graph until you get a cycle, then to continuously increase the number of edges in that cycle by extending it using unused edges. You can read more about these algorithms at this link.

What is difference between BFS and Dijkstra's algorithms when looking for shortest path?

I was reading about Graph algorithms and I came across these two algorithms:
Dijkstra's algorithm
Breadth-first search
What is the difference between Dijkstra's algorithm and BFS while looking for the shortest-path between nodes?
I searched a lot about this but didn't get any satisfactory answer!
The rules for BFS for finding shortest-path in a graph are:
We discover all the connected vertices,
Add them in the queue and also
Store the distance (weight/length) from source u to that vertex v.
Update with path from source u to that vertex v with shortest distance and we have it!
This is exactly the same thing we do in Dijkstra's algorithm!
So why are the time complexities of these algorithms so different?
If anyone can explain it with the help of a pseudo code then I will be
very grateful!
I know I am missing something! Please help!
Breadth-first search is just Dijkstra's algorithm with all edge weights equal to 1.
Dijkstra's algorithm is conceptually breadth-first search that respects edge costs.
The process for exploring the graph is structurally the same in both cases.
When using BFS for finding the shortest path in a graph, we discover all the connected vertices, add them to the queue and also maintain the distance from source to that vertex. Now, if we find a path from source to that vertex with less distance then we update it!
We do not maintain a distance in BFS. It is for discovery of nodes.
So we put them in a general queue and pop them. Unlike in Dijikstra, where we put accumulative weight of node (after relaxation) in a priority queue and pop the min distance.
So BFS would work like Dijikstra in equal weight graph. Complexity varies because of the use of simple queue and priority queue.
Dijkstra and BFS, both are the same algorithm. As said by others members, Dijkstra using priority_queue whereas BFS using a queue. The difference is because of the way the shortest path is calculated in both algorithms.
In BFS Algorithm, for finding the shortest path we traverse in all directions and update the distance array respectively. Basically, the pseudo-code will be as follow:
distance[src] = 0;
q.push(src);
while(queue not empty) {
pop the node at front (say u)
for all its adjacent (say v)
if dist[u] + weight < dist[v]
update distance of v
push v into queue
}
The above code will also give the shortest path in a weighted graph. But the time complexity is not equal to normal BFS i.e. O(E+V). Time complexity is more than O(E+V) because many of the edges are repeated twice.
Graph-Diagram
Consider, the above graph. Dry run it for the above pseudo-code you will find that node 2 and node 3 are pushed two times into the queue and further the distance for all future nodes is updated twice.
BFS-Traversal-Working
So, assume if there is lot more nodes after 3 then the distance calculated by the first insertion of 2 will be used for all future nodes then those distance will be again updated using the second push of node 2. Same scenario with 3.
So, you can see that nodes are repeated. Hence, all nodes and edges are not traversed only once.
Dijkstra Algorithm does a smart work here...rather than traversing in all the directions it only traverses in the direction with the shortest distance, so that repetition of updation of distance is prevented.
So, to trace the shortest distance we have to use priority_queue in place of the normal queue.
Dijkstra-Algo-Working
If you try to dry run the above graph again using the Dijkstra algorithm you will find that nodes are push twice but only that node is considered which has a shorter distance.
So, all nodes are traversed only once but time complexity is more than normal BFS because of the use of priority_queue.
With SPFA algorithm, you can get shortest path with normal queue in weighted edge graph.
It is variant of bellman-ford algorithm, and it can also handle negative weights.
But on the down side, it has worse time complexity over Dijkstra's
Since you asked for psuedocode this website has visualizations with psuedocode https://visualgo.net/en/sssp

Finding all the roots in a directed graph

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.

Resources