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 thestopping conditionwill 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.

**Implementation details: **

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.

## C++

`// CPP program to find shortest distance ` `// in a multistage graph. ` `#include<bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `#define N 8 ` `#define INF INT_MAX ` ` ` `// Returns shortest distance from 0 to ` `// N-1. ` `int` `shortestDist(` `int` `graph[N][N]) { ` ` ` ` ` `// dist[i] is going to store shortest ` ` ` `// distance from node i to node N-1. ` ` ` `int` `dist[N]; ` ` ` ` ` `dist[N-1] = 0; ` ` ` ` ` `// Calculating shortest path for ` ` ` `// rest of the nodes ` ` ` `for` `(` `int` `i = N-2 ; i >= 0 ; i--) ` ` ` `{ ` ` ` ` ` `// Initialize distance from i to ` ` ` `// destination (N-1) ` ` ` `dist[i] = INF; ` ` ` ` ` `// Check all nodes of next stages ` ` ` `// to find shortest distance from ` ` ` `// i to N-1. ` ` ` `for` `(` `int` `j = i ; j < N ; j++) ` ` ` `{ ` ` ` `// Reject if no edge exists ` ` ` `if` `(graph[i][j] == INF) ` ` ` `continue` `; ` ` ` ` ` `// We apply recursive equation to ` ` ` `// distance to target through j. ` ` ` `// and compare with minimum distance ` ` ` `// so far. ` ` ` `dist[i] = min(dist[i], graph[i][j] + ` ` ` `dist[j]); ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `dist[0]; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `// Graph stored in the form of an ` ` ` `// adjacency Matrix ` ` ` `int` `graph[N][N] = ` ` ` `{{INF, 1, 2, 5, INF, INF, INF, INF}, ` ` ` `{INF, INF, INF, INF, 4, 11, INF, INF}, ` ` ` `{INF, INF, INF, INF, 9, 5, 16, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, 2, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 18}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 13}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 2}}; ` ` ` ` ` `cout << shortestDist(graph); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java program to find shortest distance ` `// in a multistage graph. ` `class` `GFG ` `{ ` ` ` ` ` `static` `int` `N = ` `8` `; ` ` ` `static` `int` `INF = Integer.MAX_VALUE; ` ` ` ` ` `// Returns shortest distance from 0 to ` ` ` `// N-1. ` ` ` `public` `static` `int` `shortestDist(` `int` `[][] graph) ` ` ` `{ ` ` ` ` ` `// dist[i] is going to store shortest ` ` ` `// distance from node i to node N-1. ` ` ` `int` `[] dist = ` `new` `int` `[N]; ` ` ` ` ` `dist[N - ` `1` `] = ` `0` `; ` ` ` ` ` `// Calculating shortest path for ` ` ` `// rest of the nodes ` ` ` `for` `(` `int` `i = N - ` `2` `; i >= ` `0` `; i--) ` ` ` `{ ` ` ` ` ` `// Initialize distance from i to ` ` ` `// destination (N-1) ` ` ` `dist[i] = INF; ` ` ` ` ` `// Check all nodes of next stages ` ` ` `// to find shortest distance from ` ` ` `// i to N-1. ` ` ` `for` `(` `int` `j = i; j < N; j++) ` ` ` `{ ` ` ` `// Reject if no edge exists ` ` ` `if` `(graph[i][j] == INF) ` ` ` `{ ` ` ` `continue` `; ` ` ` `} ` ` ` ` ` `// We apply recursive equation to ` ` ` `// distance to target through j. ` ` ` `// and compare with minimum distance ` ` ` `// so far. ` ` ` `dist[i] = Math.min(dist[i], graph[i][j] ` ` ` `+ dist[j]); ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `dist[` `0` `]; ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `main(String[] args) ` ` ` `{ ` ` ` `// Graph stored in the form of an ` ` ` `// adjacency Matrix ` ` ` `int` `[][] graph = ` `new` `int` `[][]{{INF, ` `1` `, ` `2` `, ` `5` `, INF, INF, INF, INF}, ` ` ` `{INF, INF, INF, INF, ` `4` `, ` `11` `, INF, INF}, ` ` ` `{INF, INF, INF, INF, ` `9` `, ` `5` `, ` `16` `, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, ` `2` `, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, ` `18` `}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, ` `13` `}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, ` `2` `}}; ` ` ` ` ` `System.out.println(shortestDist(graph)); ` ` ` `} ` `} ` ` ` `// This code has been contributed by 29AjayKumar ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 program to find shortest ` `# distance in a multistage graph. ` ` ` `# Returns shortest distance from ` `# 0 to N-1. ` `def` `shortestDist(graph): ` ` ` `global` `INF ` ` ` ` ` `# dist[i] is going to store shortest ` ` ` `# distance from node i to node N-1. ` ` ` `dist ` `=` `[` `0` `] ` `*` `N ` ` ` ` ` `dist[N ` `-` `1` `] ` `=` `0` ` ` ` ` `# Calculating shortest path ` ` ` `# for rest of the nodes ` ` ` `for` `i ` `in` `range` `(N ` `-` `2` `, ` `-` `1` `, ` `-` `1` `): ` ` ` ` ` `# Initialize distance from ` ` ` `# i to destination (N-1) ` ` ` `dist[i] ` `=` `INF ` ` ` ` ` `# Check all nodes of next stages ` ` ` `# to find shortest distance from ` ` ` `# i to N-1. ` ` ` `for` `j ` `in` `range` `(N): ` ` ` ` ` `# Reject if no edge exists ` ` ` `if` `graph[i][j] ` `=` `=` `INF: ` ` ` `continue` ` ` ` ` `# We apply recursive equation to ` ` ` `# distance to target through j. ` ` ` `# and compare with minimum ` ` ` `# distance so far. ` ` ` `dist[i] ` `=` `min` `(dist[i], ` ` ` `graph[i][j] ` `+` `dist[j]) ` ` ` ` ` `return` `dist[` `0` `] ` ` ` `# Driver code ` `N ` `=` `8` `INF ` `=` `999999999999` ` ` `# Graph stored in the form of an ` `# adjacency Matrix ` `graph ` `=` `[[INF, ` `1` `, ` `2` `, ` `5` `, INF, INF, INF, INF], ` ` ` `[INF, INF, INF, INF, ` `4` `, ` `11` `, INF, INF], ` ` ` `[INF, INF, INF, INF, ` `9` `, ` `5` `, ` `16` `, INF], ` ` ` `[INF, INF, INF, INF, INF, INF, ` `2` `, INF], ` ` ` `[INF, INF, INF, INF, INF, INF, INF, ` `18` `], ` ` ` `[INF, INF, INF, INF, INF, INF, INF, ` `13` `], ` ` ` `[INF, INF, INF, INF, INF, INF, INF, ` `2` `]] ` ` ` `print` `(shortestDist(graph)) ` ` ` `# This code is contributed by PranchalK ` |

*chevron_right*

*filter_none*

## C#

`// C# program to find shortest distance ` `// in a multistage graph. ` `using` `System; ` ` ` `class` `GFG ` `{ ` ` ` `static` `int` `N = 8; ` ` ` `static` `int` `INF = ` `int` `.MaxValue; ` ` ` ` ` `// Returns shortest distance from 0 to ` ` ` `// N-1. ` ` ` `public` `static` `int` `shortestDist(` `int` `[,] graph) { ` ` ` ` ` `// dist[i] is going to store shortest ` ` ` `// distance from node i to node N-1. ` ` ` `int` `[] dist = ` `new` `int` `[N]; ` ` ` ` ` `dist[N-1] = 0; ` ` ` ` ` `// Calculating shortest path for ` ` ` `// rest of the nodes ` ` ` `for` `(` `int` `i = N-2 ; i >= 0 ; i--) ` ` ` `{ ` ` ` ` ` `// Initialize distance from i to ` ` ` `// destination (N-1) ` ` ` `dist[i] = INF; ` ` ` ` ` `// Check all nodes of next stages ` ` ` `// to find shortest distance from ` ` ` `// i to N-1. ` ` ` `for` `(` `int` `j = i ; j < N ; j++) ` ` ` `{ ` ` ` `// Reject if no edge exists ` ` ` `if` `(graph[i,j] == INF) ` ` ` `continue` `; ` ` ` ` ` `// We apply recursive equation to ` ` ` `// distance to target through j. ` ` ` `// and compare with minimum distance ` ` ` `// so far. ` ` ` `dist[i] = Math.Min(dist[i], graph[i,j] + ` ` ` `dist[j]); ` ` ` `} ` ` ` `} ` ` ` ` ` `return` `dist[0]; ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `static` `void` `Main() ` ` ` `{ ` ` ` `// Graph stored in the form of an ` ` ` `// adjacency Matrix ` ` ` `int` `[,] graph = ` `new` `int` `[,] ` ` ` `{{INF, 1, 2, 5, INF, INF, INF, INF}, ` ` ` `{INF, INF, INF, INF, 4, 11, INF, INF}, ` ` ` `{INF, INF, INF, INF, 9, 5, 16, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, 2, INF}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 18}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 13}, ` ` ` `{INF, INF, INF, INF, INF, INF, INF, 2}}; ` ` ` ` ` `Console.Write(shortestDist(graph)); ` ` ` `} ` `} ` ` ` `// This code is contributed by DrRoot_ ` |

*chevron_right*

*filter_none*

**Output:**

9

**Time Complexity :** O(n^{2})