Given a directed graph, and one of the vertices x, I need to find a strongly connected component in the graph that includes x.
The algorithm should be linear, and to use bfs only.
I don't know how this got to the top of my page after all this time but it's missing an answer, so...
To find the strongly connected component that contains a given node x, you can do a BFS from x to find all the nodes reachable from x. Then reverse all the edges and do a BFS from x to find all the nodes reachable through reverse edges. Those are all the nodes in the original graph from which x can be reached.
The intersection of those sets of nodes is the SCC that contains x.
Related
If you don't know how SCC algorithm works read this article: https://www.hackerearth.com/practice/algorithms/graphs/strongly-connected-components/tutorial/ (This is the best article I could find).
After finding finish time for each node, we reverse the original graph and start to run DFS from highest time node. What if we start to run DFS from smallest node in the original graph? Why it doesn't work?
Thats because the first DSF's finish times give you the topological order (which means one edge depends on another).
SCC means the every nodes are reachable from every other nodes in the component.
If you start from the smallest node (so backward) the algorithm will give false result, because in the transposed graph somewhere it wont find a way between two nodes which actually connect, or find an incorrect way because you 'walk throught' a node before its 'parent'.
Simple example (-> means depend on). Start from X the topological order: X,Y,Z,W
X -> Y -> Z
^ /
\ ˘
W
If you transpose the one above and start from Z, it will look like the whole graph is one SCC. But it is not. You must process the parent element before child. So if you start from X you cannot go into Z in the original graph before Y, also cannot go into W before Y. In the transposed graph there are a route between Z and Y but you can only use it if the invere was there in the original graph. And TO describe that there was or wasnt it. If a node topologically preceed another route and there is a route in the transposed graph between them then they strongly connected.
First of all, I have to admit I'm not good at graph theory.
I have a weakly connected directed graph G=(V,E) where V is about 16 millions and E is about 180 millions.
For a given set S, which is a subset of V (size of S will be around 30), is it possible to find a weakly connected sub-graph G'=(V',E') where S is a subset of V' but try to keep the number of V' and E' as small as possible?
The graph G may change and I hope there's a way to find the sub-graph in real time. (When a process is writing into G, G will be locked, so don't worry about G get changed when your sub-graph calculation is still running.)
My current solution is find the shortest path for each pair of vertex in S and merge those paths to get the sub-graph. The result is OK but the running time is pretty expensive.
Is there a better way to solve this problem?
If you're happy with the results from your current approach, then it's certainly possible to do at least as well a lot faster:
Assign each vertex in S to a set in a disjoint set data structure: https://en.wikipedia.org/wiki/Disjoint-set_data_structure. Then:
Do a breadth-first-search of the graph, starting with S as the root set.
When you the search discovers a new vertex, remember its predecessor and assign it to the same set as its predecessor.
When you discover an edge that connects two sets, merge the sets and follow the predecessor links to add the connecting path to G'
Another way to think about doing exactly the same thing:
Sort all the edges in E according to their distance from S. You can use BFS discovery order for this
Use Kruskal's algorithm to generate a spanning tree for G, processing the edges in that order (https://en.wikipedia.org/wiki/Kruskal%27s_algorithm)
Pick a root in S, and remove any subtrees that don't contain a member of S. When you're done, every leaf will be in S.
This will not necessarily find the smallest possible subgraph, but it will minimize its maximum distance from S.
I am trying to solve this question but got stuck.
Need some help,Thanks.
Given an undirected Connected graph G with non-negative values at edges.
Let A be a subgroup of V(G), where V(G) is the group of vertices in G.
-Find a pair of vertices (a,b) that belongs to A, such that the weight of the shortest path between them in G is minimal, in O((E+V)*log(v)))
I got the idea of using Dijkstra's algorithm in each node which will give me O(V*((E+V)logv))),which is too much.
So thought about connecting the vertices in A somehow,did'nt find any useful way.
Also tried changing the way Dijkstra's algorithm work,But it get's to hard to prove with no improvment in time complexity.
Note that if the optimal pair is (a, b), then from every node u in the optimal path, a and b are the closest two nodes in A.
I believe we should extend Dijkstra's algorithm in the following manners:
Start with all nodes in A, instead of a single source_node.
For each node, don't just remember the shortest_distance and the previous_node, but also the closest_source_node to remember which node in A gave the shortest distance.
Also, for each node, remember the second_shortest_distance, the second_closest_source_node, and previous_for_second_closest_source_node (shorter name suggestions are welcome). Make sure that second_closest_source_node is never the closest_source_node. Also, think carefully about how you update these variables, the optimal path for a node can become part of the second best path for it's neighbour.
Visit the entire graph, don't just stop at the first node whose closest_source and second_closest_source are found.
Once the entire graph is covered, search for the node whose shortest_distance + second_shortest_distance is smallest.
Here is the full question:
Assume we have a directed graph G = (V,E), we want to find a graph G' = (V,E') that has the following properties:
G' has same connected components as G
G' has same component graph as G
E' is minimized. That is, E' is as small as possible.
Here is what I got:
First, run the strongly connected components algorithm. Now we have the strongly connected components. Now go to each strong connected component and within that SCC make a simple cycle; that is, a cycle where the only nodes that are repeated are the start/finish nodes. This will minimize the edges within each SCC.
Now, we need to minimize the edges between the SCCs. Alas, I can't think of a way of doing this.
My 2 questions are: (1) Does the algorithm prior to the part about minimizing edges between SCCs sound right? (2) How does one go about minimizing the edges between SCCs.
For (2), I know that this is equivalent to minimizing the number of edges in a DAG. (Think of the SCCs as the vertices). But this doesn't seem to help me.
The algorithm seems right, as long as you allow for closed walks (i.e. repeating vertices.) Proper cycles might not exist (e.g. in an "8" shaped component) and finding them is NP-hard.
It seems that it is sufficient to group the inter-component edges by ordered pairs of components they connect and leave only one edge in each group.
Regarding the step 2,minimize the edges between the SCCs, you could randomly select a vertex, and run DFS, only keeping the longest path for each pair of (root, end), while removing other paths. Store all the vertices searched in a list L.
Choose another vertex, if it exists in L, skip to the next vertex; if not, repeat the procedure above.
I have a set of nodes and set of directed edges between them. The edges have no weight.
How can I found minimal number of edges which has to be added to make the graph strongly connected (ie. there should be a path from every node to all others)? Does this problem have a name?
It's a really classical graph problem.
Run algorithm like Tarjan-SCC algorithm to find all SCCs. Consider
each SCC as a new vertice, link a edge between these new
vertices according to the origin graph, we can get a new graph.
Obviously, the new graph is a Directed Acyclic Graph(DAG).
In the DAG, find all vertices whose in-degree is 0, we define them
{X}; find all vertices whose out-degree is 0, we define
them {Y}.
If DAG has only one vertice, the answer is 0; otherwise, the answer
is max(|X|, |Y|).
Off the top of my head, it seems the simplest (fewest edges) way to make a directed graph strongly connected would be to just have a cycle involving all nodes; so the minimum number of edges would just be N where N is the number of nodes. If there are already edges, just do something like connect longest existing directed path to the next longest path that doesn't overlap with your current path, until you form a complete cycle (once your path contains all nodes, connect the ends to form the cycle.)
Not sure if there is a more formal definition of any of this, but is seems logical to me.
I would find all weakly connected components, and tie them up in a cycle.
EDIT:
To be more explicit, the idea is if you have WCCs W(1),...,W(n),
make all of W(i%n + 1) reachable from any node in W(i), for i=1 to n.