DFS on undirected graph complexity? - algorithm

As when we traverse the undirected connected graph using DFS and mark out only edges which we travel during DFS, we end up with a DFS tree which is basically a tree and traversing a tree requires O(v) complexity where v is the number of vertices, then why it stated that complexity is O(v + e)?
I know it's a noob question but I am confused.

The DFS tree is the tree made of the edges you traversed. You indeed only traverse O(V) edges. But in order to traverse an edge, you first examine the edge to check if it will lead to a vertex you already encountered. This means you examine more edges than you traverse. Indeed, you examine O(E) edges. So the total work is O(V+E).
Note: Because your graph is connected, you are sure that E > V. In that case the complexity can be rewritten O(E).

you find all the nodes of graph through edges so the time complexity depends upon no. of edges as well that's why the O(e) is also included. If you consider complete graph TC will be O(V^2).

Consider two different graphs:
A graph having more edges than vertices, for instance a connected graph with a high minimum degree.
When the DFS algorithm visits a vertex, it will have to follow each of the edges that connect this vertex, repeating a DFS traversal from the neighboring vertices. Of course, if that neighbor was already visited, the DFS algorithm will backtrack, but at least we can state that the edge had to be processed.
This procedure will process all edges of the graph. So in this case we can say the algorithm is O(e)
A graph having fewer edges than vertices, often a disconnected graph (in the extreme case there are no edges).
When the DFS algorithm has visited all vertices that it can reach from a traversal that started in vertex A, it must still iterate over the remaining vertices, to find vertices that might not have been visited. These unvisted vertices do not belong to the same connected component). Another DFS traversal must start from there.
This way all vertices are processed. So in this case the algorithm has a O(v) time complexity
So in general, the algorithm has a O(max(e, v)) time complexity. You could also say that the algorithm must visit all edges and all vertices, and so the algorithm has a O(e+v) time complexity. Both are equivalent.

Related

How can I find an MST from all trees containing a given edge?

In a weighted undirected graph, I need to modify Kruskal's algorithm to find the MST conditional to the fact that it includes a given edge 'e' in O(m log n) time. How can I do that?
Consider kruskal's algorithm:
sort all edges in increasing order of edge weight
for every edge from u->v with weight w in the list:
if u and v are not connected, take this edge
This algorithm at any step does not consider the graph to be "individual" nodes; rather, they are all components that can be connected by any arbitrary node within the component. Thus, if we want to force some edges to be taken in the MST, we can simply connect them before running kruskal's, and remove the edge(s) forced from the edge list provided to kruskal's.

Weighted Directed Graph best method for shortest path

For a question I was doing I'm confused about why the answer would be a BFS and not Dijkstra's algorithm.
The question was : There is a weighted digraph G=(V,E) with n nodes and m edges. Each node has a weight of 1 or 2. The question was to figure out which algorithm to use to find the shortest path in G from a given vetex u to a given vertex v. The options were:
a) O(n+m) time using a modified BFS
b) O(n+m) time using a modified DFS
c) O(mlogn) time using Dijkstra's Algorithm
d) O(n^3) time using modified Floyd-Warshall algorithm
The answer is a) O(n+m) time using a modified BFS,
I know that when comparing BFS to DFS, BFS is better for shorter paths. I also know Dijkstra's algorithm is similar to a BFS and if I'm not mistaken Dijkstra's algorithm is better for weighted graphs like in this case. I'm assuming BFS is better because it says modified BFS but what would modified exactly mean or is there another reason BFS would be better.
Since all paths are limited to either a distance of 1 or 2, for every edge of length 2 from nodes a to b you can just create a new node c with an edge from a to c of length 1 and an edge from c to b of length 1, and then this becomes a graph with only edges of weight 1 which can be BFS'd normally to find shortest path from u to v. Since you only add O(m) new nodes and O(m) new edges, this keeps the BFS's time complexity of O(n+m).
Another possibility is to, at each layer of BFS, store another list of nodes that are attained by edges with a weight of 2 from the current layer, and consider them at the same time as nodes attained two layers later. This approach is a bit more finicky though.

How can I check if a given spanning tree is a MST?

Suppose we are given a graph G and a spanning tree T of it. How can we check that if this spanning tree is a MST or not?
I suggest that for each edge i that is not in T, all edges j on the unique path of T from one end of i to the other end, we must have w_i >= w_j
You want to check that for each edge (u, v) not in the MST, the path from u to v in the MST has no edge with weight larger than that of (u, v). For a single vertex in the tree, you can use a single BFS or DFS to find the largest-weight edge on the path to all other nodes, so this gives an O(n2) algorithm (n times O(n) search). You can probably do better by not starting from scratch for each vertex. That said, it may be more efficient to just calculate an MST and see if the sum of all edge weights is the same. As mentioned by #Niklas in the comments, there are linear time methods for verifying an MST, but they seem to be significantly more involved.

Recursive minimal spanning tree algorithms

Is this a right algorithm for finding minimal spanning tree.
Divide Graph into 2 equally connected parts. Find its minimal spanning trees. Connect them using the smallest edge that connects them. I am trying to get counterexample of this algorithm, but can't.
Consider a four-node graph, connected in a square, with the left edge having cost 10 and all other edges having cost 1. If you divide the graph into left and right for your recursive step, you will end up with a spanning tree of cost 12, instead of cost 3.
MST is not well-adapted to "divide-and-conquer" algorithms. The closest thing is probably the Reverse-Delete algorithm; whenever you fail to remove an edge (because it would disconnect the graph), you can think of the remaining steps as executing recursively on the two sides of that edge.
You have described a divide and conquer algorithm which will not work when determining an MST. Sneftel provided a good counter-example and recursively dividing the graph into two connected parts would be extremely costly.
Instead, a good approach to finding an MST would be to use a greedy algorithm such as Prim's algorithm. We know a greedy algorithm will work because this problem exhibits optimal substructure. For this algorithm, you will want to represent your graph as an adjacency list. First, start at an arbitrary node and add it to a visited list. Add all edges from this node into a min-heap. Include the cheapest edge in your MST and add the connecting node to your visited list. From that node add all edges to your min-heap and then select the cheapest edge to a node that has yet to be visited. Continue doing so until all nodes are visited. Once that is done you have your MST.
You can use other data structures to store the graph and the visited edges, but the ones I have outlined above will maximize the runtime. If we analyze the run-time with these data structures we can see that the runtime is O(E log V) which is the time to update the cost of the elements and maintaining your heap after an edge has been removed. More specifically O(log V) to fix the heap and that is done E number of times.
I also found this quick 2-minute video that outlines Prim's algorithm with an example: Prim's Algorithm in 2 Minutes
I hope this information is helpful!

MST-related algorithm

Given an undirected and connected graph G(V,E) with weight function w:E->R, an edge e(u,v) belongs to E. Which algorithm that runs in linear run-time complexity can assure if there's a minimal spanning tree that contains the edge e?
Perform depth-first search starting from u and ignoring any edge with weight equal to weight of given edge or heavier. If DFS completes without visiting v, this means there is no cycle where given edge is the heaviest edge, therefore given edge is contained in some minimal spanning tree.
This is asking you to implement Prim's Minimum Spanning Tree twice.
The first time run the algorithm as normal. Make a note of the weight of the mst.
The second time, instead of starting with an empty tree as Prim's algorithm normally does, start with the nodes u and v already on the tree -- which is the same as having edge e(u,v). Then continue building the mst.
at the end if the second mst is the same weight as the first mst, then edge e(u,v) can be in a mst. If not, there is a lighter mst.
By the way, 2*O(n) is still O(n)

Resources