A Multistage graph is a directed graph in which the nodes can be divided into a set of stages such that all edges are from a stage to next stage only (In other words there is no edge between vertices of same stage and from a vertex of current stage to previous stage).
We are give a multistage graph, a source and a destination, we need to find shortest path from source to destination. By convention, we consider source at stage 1 and destination as last stage.
Following is an example graph we will consider in this article :-
Now there are various strategies we can apply :-
- The Brute force method of finding all possible paths between Source and Destination and then finding the minimum. That’s the WORST possible strategy.
- Dijkstra’s Algorithm of Single Source shortest paths. This method will find shortest paths from source to all other nodes which is not required in this case. So it will take a lot of time and it doesn’t even use the SPECIAL feature that this MULTI-STAGE graph has.
- Simple Greedy Method – At each node, choose the shortest outgoing path. If we apply this approach to the example graph give above we get the solution as 1 + 4 + 18 = 23. But a quick look at the graph will show much shorter paths available than 23. So the greedy method fails !
- The best option is Dynamic Programming. So we need to find Optimal Sub-structure, Recursive Equations and Overlapping Sub-problems.
Optimal Substructure and Recursive Equation :-
We define the notation :- M(x, y) as the minimum cost to T(target node) from Stage x, Node y.
Shortest distance from stage 1, node 0 to destination, i.e., 7 is M(1, 0). // From 0, we can go to 1 or 2 or 3 to // reach 7. M(1, 0) = min(1 + M(2, 1), 2 + M(2, 2), 5 + M(2, 3))
This means that our problem of 0 —> 7 is now sub-divided into 3 sub-problems :-
So if we have total 'n' stages and target as T, then the stopping condition will be :- M(n-1, i) = i ---> T + M(n, T) = i ---> T
Recursion Tree and Overlapping Sub-Problems:-
So, the hierarchy of M(x, y) evaluations will look something like this :-
In M(i, j), i is stage number and j is node number M(1, 0) / | \ / | \ M(2, 1) M(2, 2) M(2, 3) / \ / \ / \ M(3, 4) M(3, 5) M(3, 4) M(3, 5) M(3, 6) M(3, 6) . . . . . . . . . . . . . . . . . .
So, here we have drawn a very small part of the Recursion Tree and we can already see Overlapping Sub-Problems. We can largely reduce the number of M(x, y) evaluations using Dynamic Programming.
The below implementation assumes that nodes are numbered from 0 to N-1 from first stage (source) to last stage (destination). We also assume that the input graph is multistage.
Time Complexity : O(n2)
If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to email@example.com. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
- Shortest path in an unweighted graph
- Topological Sorting
- 0-1 BFS (Shortest Path in a Binary Weight Graph)
- Prefix Sum of Matrix (Or 2D Array)
- All Topological Sorts of a Directed Acyclic Graph
- Modulo power for large numbers represented as strings
- Number of ways to change the XOR of two numbers by swapping the bits
- Number of quadrilaterals possible from the given points
- How to read Competitive Programming Questions?
- Python in Competitive Programming