My idea of solving this problem is to adjust DFS so that it stops when we hit the destination node, then set up a counter that adds up all of the neighbors of the starting node, then the neighbors of the starting node and its neighrbours recursively.
I'm just wondering if this will only count the paths from the source to the destination, and not any stray paths that don't lead to the destination node.
Thank you for the help.
You can use dynamic programming. You have a directed acyclic graph so you have a node (say s) with no arcs pointing into s. You also have a node (say t) that has no arcs pointing out of t. Because it is acyclic, you can use a topological sorting algorithm to find an ordering of the nodes such that every arc points away from s and towards t.
So start at s. The number of paths from s to s is 1, the empty path. Because the graph is acyclic, s must have a neighbour u such that the only arc pointing into u is su. Now you just repeat. In general, for a node w that has arcs from v1,...vk pointing into it. Then the number of paths from s to w is just the sum of the number of sv1 paths, ..., svk paths.
This is in the case of a single arc between each node. If there are multiple arcs you multiply so it would be (number of v1w arcs)(number of sv1paths) + ... + (number of vkw arcs)(number of svk paths)
And at each step you can use the fact that it is acyclic to find the node w such that you have already calculated all the sv1 to svk paths.
I would use BFS.
Let's call the source node s and the target node t.
When you BFS starting from s, all the paths with length 1 will be found and put into a queue. You can, then, take the first element of the queue (call it u) and find all the paths of size 2 (s -> u -> ...). Repeat the same thing for each distance, until you find all paths of all lengths from s to t.
A trick to speed it up would be: after you exhausted all the paths of a node w, store how many paths from w to t there are, and when another node (above w) reach w, you won't need to recompute all the paths.
Related
Given an undirected weighted graph, a start, and an end point. You need to find the shortest path to that end point, but throw an error if multiple shortest paths are found. How would we do the error part? Is there a way to check if multiple shortest paths to a destination node exist?
My idea is that when we pop out of the priority queue in dijkstra's algorithm, at that time if the node is the destination node, then we check if in this priority queue, another element exists for the same destination node.
During the relaxation, instead of only pushing to the queue if the distance is less than, we can push if the distance is less than or equal to. But I am not sure about it.
EDIT - Its a weighted undirected graph
One way to do this is by creating a shortest path DAG. Whenever you relax some edge from node A to node B with cost C (assuming the current shortest distance from source to each node is stored in array dist), if dist[A] + C is greater than dist[B] then do nothing, if dist[A] + C is equal to dist[B], then we can reach B in a shortest path using a different route than before, so we add A to the list of nodes that can reach B in its shortest path (let's call this array pars), so we add A to pars of B, and finally if dist[A] + C is less than dist[B], then we update dist[B] and clear the previous values from pars[B], and add A to pars[B].
The resulting graph is guaranteed to be a DAG if all edge weights are strictly greater than 0. Then you can count the number of paths to the destination node using some easy dynamic programming methods, process node in a topological order, then the number of paths of each node is the sum of number of paths of nodes that reach it (nodes in pars[node]).
Hopefully this was useful and clear.
Given a network flow G(V,E). After we run FF algorithm and get a residual grpah Gf and a min-cut (S,T)
I want to know a minimum number of edges Eā²ā E such that increasing capacity of each e ā E by one unit will increase the max flow to val(f)+1. The algorithm should run in O(E*log(V)).
Here is my approach.
For each cross edge (u,v)
(1) Use BFS to find partial augmenting path s to u; and all partial augmenting path from v to t. If both such partial augmenting path exists. Then increase the (u,v) can make max flow increase by one.
If (1) is false,
There are few possibility
(a) In residual, source s has no outgoing edge
(b) In residual, sink t has no incoming edge.
(c) both of above happens
In case of (a), the min-cut has one set contains only source s. Find the shortest path from cross edge to t, this distance + 1 (the cross edge) will be our minimal. By using Dijlstra algorithm in O(E*log(V)) time
In case of (b), similarly, find the shortest path from a cross edge to t (let's say this cross edge is (u,v) and v in T, v to t is the shortest path for all cross edge), this distance + 1 + the distance of shortest path from s to u = minimal number of edges that increase all its capacity by one, leads to max flow increase by one
In case of (c), we need to look for a shortest path from s to t; we can apply Dijlstra algorithm in O(E*log(V)) time.
However, I think the above approach can achieve the goal but not very efficient (especially in dealing with case (2), it might not run in E*log(V) time).
Is there easier way of approaching?
If capacities are integers then this seems reasonably straightforward.
From S use depth first search to find all of the nodes reachable from there using links with spare capacity. Put these nodes in a set and mark them.
From T use depth first search to find all of the nodes that can reach T using links with spare capacity. Mark these nodes differently.
Use breadth first search to find the shortest path from any node reachable from S to any node that can reach T. Start with the set of nodes reachable from S. At each stage look it see if any node that can reach T is a neighbour of a node in the current set. If so then you are finished. If not, then the set for the next stage is the set of neighbours of nodes in the current set that are not marked. Mark all of the nodes in the new set.
If the capacities are not integers, so that creating any flow does not give you a flow of capacity at least one, then I think you are in the land of https://en.wikipedia.org/wiki/Minimum-cost_flow_problem.
I need help with this problem that I'm currently working on, which involves finding a node v in an undirected graph that, when removed, will destroy all paths between two other nodes s and t.
Suppose that an n-node undirected graph G = (V, E) contains two nodes s and t such that the distance between s and t is strictly greater than n/2. Show that there must exist some node v, not equal to either s or t, such that deleting v from G destroys all s-t paths. (In other words, the graph obtained from G by deleting v contains no path from s to t.)
Give an algorithm with running time O(m + n) to find such a node v.
(For solution, you can use either plain English or pseudo code.)
My understanding of this is that the solution would involve creating a breadth-first search that finds the node v and removes it, but I'm not certain of how to prove that removing the node exists in the first place such that removing it would destroy all s-t paths.
First the prove part:
Let's assume v node does not exist which means there is at least two path using totally different nodes from s to t, and the distance is greater than n / 2. This is impossible since you do not even have enough number of nodes for this two path. So this contradicts our assumption there for v node exist.
Second part algorithm:
Use bidirectional BFS. Since v node's exist if you start to search from s and t, they will definitely meet at v nodes. And in the worst case you go thru all the V and E, so it is O(V + E).
In an acyclic graph, I am trying to find out whether or not a path of length L exists between two given nodes. My questions is, what is the best and the simplest Algorithm to use in this case.
Note that the graph has a maximum of 50 nodes and 100 edges.
I have tried to find all the paths using DFS and then to check if that path exists between the two nodes but I got the answer "Time Limit Exceeded" from the online judge.
I also used the Uniform Cost Search Algorithm but I also a got a negative response.
I need a more efficient way for solving such problem. Thank you.
I don't know if it will be faster then a DFS approach - but it will give a feasible solution:
Represent the graph as a matrix A, and calculate A^L - a path of length L between i and j exists if and only if A[i][j] != 0
Also, regarding DFS solution: You do not need to find all paths in the DFS - you should limit yourself to paths of length <= L, and by this trim some searches, once the length have exceeded the needed length. You could also escape the search once a path of length L is reaching the target.
Another possible optimization could be bi-directional search.
Find all vertices which have path of length L/2 from the source to
them.
Next, find all vertices which have paths of length L/2 from them
to the target (DFS on the reverse graph)
Then, check if there is a vertex that is common to both sets, if
there is - you got a path of length L from the source to the target.
Since the graph is acyclic you can order vertices topologicaly.
Let's name starting vertex A and finish vertex B.
Now the core algorithm starts:
For each vertex count all possible distances from A to this vertex. At start there is
one path from A to A with length zero.
Then take vertices in topological order.
When you pick vertex x: Look at each predecessor and update possible distances here.
This should run in O(N^3) time.
You can use a modified Dijkstra algorithm where instead of saving for every vertex the minimum distance to the origin, you save all the possible distances less or equal to the one desired.
I believe that you can use the following algorithm to find the longest path in a tree. This assumes that your graph is connected, if it is not you would need to rerun this on each connected component:
Pick an arbitrary node, A.
Do a BFS (or DFS) from A to find the node in the tree farthest from A, call this node B.
Do a BFS (or DFS) from B to find the node in the tree farthest from B, call this node C.
The path from B to C is the longest path in the tree (possibly tied for longest).
Obviously if this path is longer than L then you can shorten it to find a path of length L.
Suppose I have a weighted non-directed graph G = (V,E). Each vertex has a list of elements.
We start in a vertex root and start looking for all occurances of elements with a value x. We wish to travel the least amount of distance (in terms of edge weight) to uncover all occurances of elements with value x.
The way I think of it, a MST will contain all vertices (and hence all vertices that satisfy our condition). Therefore the algorithm to uncover all occurances can just be done by finding the shortest path from root to all other vertices (this will be done on the MST of course).
Edit :
As Louis pointed out, the MST will not work in all cases if the root is chosen arbitrarily. However, to make things clear, the root is part of the input and therefore there will be one and only one MST possible (given that the edges have distinct weights). This spanning tree will indeed have all minimum-cost paths to all other vertices in the graph starting from the root.
I don't think this will work. Consider the following example:
x
|
3
|
y--3--root
| /
5 3
| /
| /
x
The minimum spanning tree contains all three edges with weight 3, but this is clearly not the optimum solution.
If I understand the problem correctly, you want to find the minimum-weight tree in the graph which includes all vertices labeled x. (That is, the correct answer would have total weight 8, and would be the two edges drawn vertically in this drawing.) But this does not include your arbitrarily selected root at all.
I am pretty confident that the following variation on Prim's algorithm would work. Not sure if it's optimal, though.
Let's say the label we are looking for is called L.
Use an all-pairs shortest path algorithm to compute d(v, w) for all v, w.
Pick some node labeled L; call this the root. (We can be sure that this will be in the result tree, since we are including all nodes labeled L.)
Initialize a priority queue with the root initialized to 0. (The priority queue will consist of vertices labeled L, and their minimum distance from any node in the tree, including vertices not labeled L.)
While the priority queue is nonempty, do the following:
Pick out the top vertex in the queue; call it v, and its distance from the tree d.
For each vertex w on the path from v to the tree, v inclusive, find the nearest L-labeled node x to w, and add x to the priority queue, or update its priority. Add w to the tree.
The answer is no, if I'm understanding correctly. Finding the minimum spanning tree will contain all vertices V, but you only want to find the vertices with value x. Thus, your MST result may have unneeded vertices adding extra path length and therefore be sub-optimal.
An example has been given where the MST M1 from Root differs from an MST M2 containing all x nodes but not containing Root.
Here's an example where Root is in both MST's: Let graph G contain nodes R,S,T,U,V (R=Root), and a clockwise path R-S-T-U-V-R, with edge weights 1,1,3,2,2 going clockwise, and x at R, S, T, U. The first MST, M1, will have subtrees S-T and V-U below R, with cost 6 = 2+4, and cost-3 edge T-U not included in M1. But M2 has subtree S-T-U (only) below R, at cost 5.
Negative. If the idea is to find for every node that contains 'x' a separate path from root to it, and minimize the total cost of the paths, then you can just use simple shortest-path calculation separately for every node starting from the root, and put the paths together.
Some of those shortest paths will not be in the minimum spanning tree, so if this is your goal, the MST solution does not work. MST optimizes the cost of the tree, not the sum of costs of paths from root to the nodes.
If your idea is to find one path that starts from root and traverses through all nodes that contain 'x', then this is the traveling salesman problem and it is an NP-complete optimization problem, i.e. very hard.