So it seems that determining whether an edge is in a minimum spanning tree can be reduced down to the question of whether the edge is the heaviest edge of some cycle. I know how to detect whether an edge is in a cycle, using DFS, but how to determine whether it's the heaviest edge in that cycle? Is it by just finding the cycle and picking the heaviest edge in it?
Assuming that all the edges have distinct weights, a simple and fairly elegant algorithm for doing this would be to do a modified DFS. Notice that if this edge is the heaviest edge in some cycle, then if you were to look at the graph formed by deleting all edges heavier than the current edge, there must be some path from the endpoint of the edge back to the start of the edge, because this path, combined with the edge itself, forms a cycle with the given edge being the heaviest such edge. Conversely, if there is no cycle containing the edge for which the given edge is the heaviest, then if you were to do a search in this graph from the end of the edge back to the source, you wouldn't be able to get back to the source of the edge, since otherwise you could complete it into a cycle. This gives the following simple algorithm: do a DFS in the original graph from the endpoint of the edge back to the source, but whenever you encounter an edge that is heavier than the original edge, don't process it (this simulates deleting it from the graph). If your DFS takes you from the end of the edge back to the source, then you know that there must be some cycle for which the edge is the heaviest edge, and if there is no such cycle then you won't be able to get back to the source of the edge.
In the case where the edges aren't distinct, you would do the same search as above, but you would delete all edges whose weight was greater than or equal to the weight of the current edge. The reason for this is that if there is a path from the end of the edge to the start of the edge in this transformed graph, you know for a fact that we didn't end up using any edges that have the same cost as the original edge, so any path found can be completed into a cycle where the given edge is the heaviest. If there is no path, then either
Every cycle containing the given edge has some edge that's strictly heavier than it, or
Every cycle containing the given edge has some edge that has the same cost as it.
In either case, it's not the heaviest edge in the cycle.
The runtime of this algorithm is O(m + n), the time required to do a standard DFS.
Hope this helps!
Related
I'm trying to struct an efficient algorithm gets undirected graph, and edge e(u,v), and decides if the edge belongs to some cycle in the graph ,but not all of the cycles!
My approach is to take out the edge (u,v) from the graph, and run BFS to see if v is still reachable from u. If yes then the original graph has a cycle containing e, otherwise there isn't.
But i'm not so sure how to tweak the algorithm that it will decide if the edge doesn't belong to all the cycles of the graph.
An undirected graph can contain an edge which belongs to all of its cycles graph only if this graph has a single cycle.
Let's look at an example. Edge (2,3) belongs to two cycles, but you always can find a third cycle to which such an edge doesn't belong.
After you have checked that the edge belongs to some cycle, you can check if this is the only cycle in the graph by removing this edge and checking if the reduced graph has any cycles at all. Thanks to #nomanpouigt for pointing that out.
i have an undricted graph G=(V,E) and weight function w:E->R+. also, i have the MST T of G.
I have to build an algorithm that does the follow:
if we add a new edge e' that has the weight w(e') to E. suggest an algorithm that updates T in a way that it will be MST of the new graph G'=(V,EUe').
complexity: O(V).
what i suggested is:
1) Add e' to T. we get a new graph call it T' that include one cycle.
2) Run DFS on T' and mark every vertex that you visit. and in addition save
every vertex and every edge weight in stacks.
3) When we visit a vertex that we already visited we stop running.
4) and start withdrawing from the stack till we get to the vertex we stopped at.
5) while withdrawing we save the maximum edge weight we withdraw ed from the
stack.
6) if the maximum edge weight is bigger that w(e') we replace them.
7) otherwise we remain with the same T.
i hope it's clear.
i would be very grateful if anyone could till me if it works or give me other
solutions and suggestion.
Yes the solution you suggested is correct because a graph with the same number of edges and nodes (like T) consists of a simple cycle with trees rooted at some (maybe none) of the nodes of this cycle.
You need to delete exactly 1 edge from T such that the remaining graph is still connected. Obviously the best choice is to delete the largest edge. The only edges you can delete while keeping the graph connected are the ones in the cycle (the ones you are adding to the stack).
Another solution would be to find the bridges in the graph, then finding the maximum non-bridge edge and deleting it. However since this is a special graph the solution you mentioned would be much easier (the non-bridge edges are the ones on the cycle) .
A shortest cycle is one with the minimum number of edges.
For example, given a graph:
The shortest cycles are: ACDA, DABD
If I only needed to find one shortest cycle, I would just run BFS on every vertex and keep track of the smallest cycle. But I don't know how to enumerate all smallest cycles.
There is a similar SO question on enumerating minimal cycles in a digraph, but there a minimal cycle is one which is not a union of smaller cycles. Here I am only looking for the cycles with the minimum number of edges.
Run a number of DFS searches as in topological sort: start from a random vertex, and continue running new DFS searches as long as there are some unexplored vertices.
In a search, as soon as you find a back edge, you know that (1) there's a cycle (2) the number of edges in that cycle. If you also need to get a list of edges in the cycle, keep an array for each "currently detected cycle" and fill it as you backtrack in the DFS call graph. If the back-edge was a node A->B, When you'll reach back node B, the array is going to contain all edges in the cycle.
Of course, keep in track the "shortest cycle found so far" to avoid bookkeeping edge lists for cycles that are longer than this minimum.
I have seen ways to detect a cycle in a graph, but I still have not managed to find a way to detect a "bridge-like" cycle. So let's say we have found a cycle in a connected (and undirected) graph. How can we determine whether removing this cycle will disconnect the graph or not? By removing the cycle, I mean removing the edges in the cycle (so the vertices are unaffected).
One way to do it is clearly to count the number of components before and after the removal. I'm just curious to know if there's a better way.
If there happens to be an established algorithm for that, could anyone please point me to a related work/paper/publication?
Here's the naive algorithm, complexity wise I don't think there's a more efficient way of doing the check.
Start with your list of edges (cycleEdges)
Get the set of vertices within cycleEdges (cycleVertices)
If a vertex in cycleVertices only contains edges that are part of cycleEdges return FALSE
For Each vetex In cycleVertices
Recursively follow vertex's edges that are not in cycleEdges (avoid already visited vertices)
If a vertex is reached that is not in cycleVertices add it to te set outsideVertices (stop recursively searching this path)
If only vertices that are in cycleVertices have been reached Return FALSE
If outsideVertices contains 1 element Return TRUE
Choose a vertex in outsideVertices and remove it from outsideVertices
Recursively follow that vertex's edges that are not in cycleEdges (avoid already visited vertices) (favor choosing edges that contain a vertex in outsideVertices to improve running time for large graphs)
If a vertex is reached that is in outsideVertices remove it from outsideVertices
If outsideVertices is empty Return TRUE
Return FALSE
You can do it for E+V.
You can get all bridges in your graph for E+V by dfs + dynamic programming.
http://www.geeksforgeeks.org/bridge-in-a-graph
Save them (just make boolean[E], and make true.
Then you can say for O(1) the edge is bridge or not.
You can just take all edges from your cycle and verify that it is bridge.
Vish's mentions articulation points which is definitely in the right direction. More can be said though. Articulation points can be found via a modified DFS algorithm that looks something like this:
Execute DFS, assigning each number with its DFS number (e.g. the number of nodes visited before it). When you encounter a vertex that has already been discovered compare its DFS number to the current vertex and you can store a LOW number associated with this vertex (e.g. the lowest DFS number that this node has "seen"). As you recurse back to the start vertex, you can compare the parent vertex with the child's LOW number. As you're recursing back, if a parent vertex ever sees a child's low number that is greater than or equal to its own DFS number, then that parent vertex is an articulation point.
I'm using "child" and "parent" here as descriptors a lot because in the DFS tree we have to consider a special case for the root. If it ever sees a child's low number that is greater than or equal to its own DFS number and it has two children in the tree, then the first vertex is an articulation.
Here's a useful art. point image
Another concept to be familiar with, especially for undirected graphs, is biconnected components, aka any subgraph whose vertices are in a cycle with all other vertices.
Here's a useful colored image with biconnected components
You can prove that any two biconnected components can only share one vertex max; two "shared" vertices would mean that the two are in a cycle, as well as with all the other vertices in the components so the two components are actually one large component. As you can see in the graph, any vertex shared by two components (has more than one color) is an articulation point. Removing the cycle that contains any articulation point will thus disconnect the graph.
Well, as in a cycle from any vertex x can be reached any other vertex y and vice-verse, then it's a strongly connected component, so we can contract a cycle into a single vertex that represents the cycle. The operation can be performed for O(n+m) using DFS. Now, we can apply DFS again in order to check whether the contracted cycles are articulation vertices, if they are, then removing them will disconnect a graph, else not. Total time is 2(n+m) = O(n+m)
I have the following problem on my homework:
Give an O(n+m) algorithm to find that whether an edge e would be a part of the MST of a graph
(We are allowed to get help from others on this assignment, so this isn't cheating.)
I think that I could do a BFS and find if this edge is a edge between two layers and if so whether this edge was the smallest across those layers. But what could I say when this edge is not a tree edge of the BFS tree?
As a hint, if an edge is not the heaviest edge in any cycle that contains it, there is some MST that contains that edge. To see this, consider any MST. If the MST already contains the edge, great! We're done. If not, then add the edge into the MST. This creates a cycle in the graph. Now, find the heaviest edge in that cycle and remove it from the graph. Everything is now still connected (because if two nodes used to be connected by a path that went across that edge, now they can be connected by just going around the cycle the other way). Moreover, since the cost of the edge was deleted wasn't any smaller than the cost of the edge in question (because the edge isn't the heaviest edge in the cycle), the cost of this tree can't be any greater than before. Since we started with an MST, we must therefore end with an MST.
Using this property, see if you can find whether the edge is the heaviest edge on any cycle in linear time.
We will solve this using MST cycle property, which says that, "For any cycle C in the graph, if the weight of an edge e of C is larger than the weights of all other edges of C, then this edge cannot belong to an MST."
Now, run the following O(E+V) algorithm to test if the edge E connecting vertices u and v will be a part of some MST or not.
Step 1
Run dfs from one of the end-points(either u or v) of the edge E considering only those edges that have weight less than that of E.
Step 2
Case 1
If at the end of this dfs, the vertices u and v get connected, then edge E cannot be a part of some MST. This is because in this case there definitely exists a cycle in the graph with the edge E having the maximum weight and it cannot be a part of the MST(from the cycle property).
Case 2
But if at the end of the dfs u and v stay disconnected, then edge E must be the part of some MST as in this case E is never the maximum weight edge of the cycles that it is a part of.
Find if there are any paths that are cheaper than the current one (u,v) that creates a cycle to u and v. If yes, then (u,v) is not on the mst. Otherwise it is. This can be proved by the cut property and the cycle property.