GFG App
Open App
Browser
Continue

# Shortest path with maximum score and fixed start/end node

Given a graph with N nodes and M edges with array A[] and integer C, the task is to find the maximum score. If visiting node i gives A[i] points for all i from 1 to N. It is necessary to start the traversal from node 1 and end the traversal on node 1. The cost of traversal is C * T2 where T is the distance traveled.

Examples:

Input: A[] = {0, 10, 20}, edges[][2] = { {1, 2}, {2, 3}, {3, 1} }, C = 1
Output: 24
Explanation:

• The optimal traversal is 1 -> 2 -> 3 -> 1 -> 2 -> 3 -> 1
• T = Total Distance travelled = 6
• The cost is 10 (1 -> 2) + 20 (2 -> 3) + 0 (3 -> 1) + 10 (1 -> 2)  + 20 (2 -> 3) + 0 (3 -> 1) – C * T2 = 60 – C * T2 = 60 – 1 * 62 = 24

example 1 :

Input: A[] = {0, 10, 20}, edges[][2] = { {1, 2}, {2, 3}, {3, 1} }, C= 100
Output: 0
Explanation: It’s optimal not to traverse at all.

Naive approach: The basic way to solve the problem is as follows:

The basic way to solve this problem is to generate all possible combinations by using a recursive approach.

Time Complexity: O(N!)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea:

Dynamic programming can be used to solve this problem

• dp[i][j] = the maximum score on traversing node i’th time ending on node j.
• recurrence relation: dp[curTime][u] = max(dp[curTime][u], dp[curTime – 1][i] + A[u]);

Follow the steps below to solve the problem:

• Declare a 2d array dp[maxTime][N] with all values initialized to -1 indicating no node is visited yet.
• Base case dp[0][0] = 0, if we do not travel at all we get 0 coins.
• Initialize the answer variable to keep track of the max score.
• Iterate on all and for each day iterate on all nodes.
• At the end of each day keep track of the maximum value possible.

Below is the implementation of the above approach:

## C++

 `// C++ code to implement the approach` `#include ` `using` `namespace` `std;`   `// Function to calculate maximum coins` `// during trips` `void` `maximumCoins(``int` `A[], ``int` `N, ``int` `edg[][2], ``int` `M,` `                  ``int` `C)` `{`   `    ``// Adjecency list` `    ``vector > adj(N);`   `    ``for` `(``int` `i = 0; i < M; i++) {`   `        ``// Travel from edg[i][0]` `        ``// to edg[i][1]` `        ``adj[--edg[i][0]].push_back(--edg[i][1]);` `    ``}`   `    ``// dp table initialized with -1` `    ``// indicating not visited` `    ``vector > dp(1001, vector<``int``>(N, -1));`   `    ``// Base case` `    ``dp[0][0] = 0;`   `    ``int` `ans = 0;`   `    ``// Simulating time from 0 to 1000` `    ``for` `(``int` `curTime = 0; curTime < 1000; curTime++) {`   `        ``// At each unit time iterate` `        ``// on each node` `        ``for` `(``int` `i = 0; i < N; i++) {`   `            ``// If dp[d][i] == -1 then the` `            ``// node can't be visited` `            ``if` `(dp[curTime][i] != -1) {` `                ``for` `(``int` `u : adj[i]) {`   `                    ``// dp[curTime + 1][u]` `                    ``// is max(current coins` `                    ``// earned, previous` `                    ``// node's earnings +` `                    ``// current node's` `                    ``// earnings)` `                    ``dp[curTime + 1][u]` `                        ``= max(dp[curTime + 1][u],` `                              ``dp[curTime][i] + A[u]);` `                ``}` `            ``}` `        ``}` `        ``ans = max(ans, (dp[curTime][0]` `                        ``- (C * curTime * curTime)));` `    ``}`   `    ``cout << ans << ``"\n"``;` `}`   `// Driver Code` `int` `main()` `{`   `    ``// Input 1` `    ``int` `A[] = { 0, 10, 20 },` `        ``edges[][2] = { { 1, 2 }, { 2, 3 }, { 3, 1 } },` `        ``C = 1;` `    ``int` `N = ``sizeof``(A) / ``sizeof``(A[0]);` `    ``int` `M = 3;`   `    ``// Function Call` `    ``maximumCoins(A, N, edges, M, C);`   `    ``// Input 2` `    ``int` `A1[] = { 0, 10, 20 },` `        ``edges1[][2] = { { 1, 2 }, { 2, 3 }, { 3, 1 } },` `        ``C1 = 10;` `    ``int` `N1 = ``sizeof``(A1) / ``sizeof``(A1[0]);` `    ``int` `M1 = 3;`   `    ``// Function Call` `    ``maximumCoins(A1, N1, edges1, M1, C1);` `    ``return` `0;` `}`

## Java

 `import` `java.util.*;`   `public` `class` `Main {`   `    ``// Function to calculate maximum coins during trips` `    ``public` `static` `void` `    ``maximumCoins(``int``[] A, ``int` `N, ``int``[][] edg, ``int` `M, ``int` `C)` `    ``{`   `        ``// Adjacency list` `        ``ArrayList > adj` `            ``= ``new` `ArrayList >();` `        ``for` `(``int` `i = ``0``; i < N; i++) {` `            ``adj.add(``new` `ArrayList());` `        ``}`   `        ``for` `(``int` `i = ``0``; i < M; i++) {`   `            ``// Travel from edg[i][0] to edg[i][1]` `            ``adj.get(edg[i][``0``] - ``1``).add(edg[i][``1``] - ``1``);` `        ``}`   `        ``// dp table initialized with -1 indicating not` `        ``// visited` `        ``int``[][] dp = ``new` `int``[``1001``][N];` `        ``for` `(``int` `i = ``0``; i < ``1001``; i++) {` `            ``Arrays.fill(dp[i], -``1``);` `        ``}`   `        ``// Base case` `        ``dp[``0``][``0``] = ``0``;`   `        ``int` `ans = ``0``;`   `        ``// Simulating time from 0 to 1000` `        ``for` `(``int` `curTime = ``0``; curTime < ``1000``; curTime++) {`   `            ``// At each unit time iterate on each node` `            ``for` `(``int` `i = ``0``; i < N; i++) {`   `                ``// If dp[d][i] == -1 then the node can't be` `                ``// visited` `                ``if` `(dp[curTime][i] != -``1``) {` `                    ``for` `(``int` `u : adj.get(i)) {`   `                        ``// dp[curTime + 1][u] is max(current` `                        ``// coins earned, previous node's` `                        ``// earnings + current node's` `                        ``// earnings)` `                        ``dp[curTime + ``1``][u] = Math.max(` `                            ``dp[curTime + ``1``][u],` `                            ``dp[curTime][i] + A[u]);` `                    ``}` `                ``}` `            ``}` `            ``ans = Math.max(` `                ``ans,` `                ``(dp[curTime][``0``] - (C * curTime * curTime)));` `        ``}`   `        ``System.out.println(ans);` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `main(String[] args)` `    ``{`   `        ``// Input 1` `        ``int``[] A = { ``0``, ``10``, ``20` `};` `        ``int``[][] edges = { { ``1``, ``2` `}, { ``2``, ``3` `}, { ``3``, ``1` `} };` `        ``int` `C = ``1``;` `        ``int` `N = A.length;` `        ``int` `M = ``3``;`   `        ``// Function Call` `        ``maximumCoins(A, N, edges, M, C);`   `        ``// Input 2` `        ``int``[] A1 = { ``0``, ``10``, ``20` `};` `        ``int``[][] edges1 = { { ``1``, ``2` `}, { ``2``, ``3` `}, { ``3``, ``1` `} };` `        ``int` `C1 = ``10``;` `        ``int` `N1 = A1.length;` `        ``int` `M1 = ``3``;`   `        ``// Function Call` `        ``maximumCoins(A1, N1, edges1, M1, C1);` `    ``}` `}`   `// This code is contributed by Prajwal Kandekar`

## Python3

 `# Python code to implement the approach`   `# Function to calculate maximum coins` `# during trips`     `def` `maximumCoins(A, N, edg, M, C):`   `    ``# Adjacency list` `    ``adj ``=` `[[] ``for` `i ``in` `range``(N)]`   `    ``for` `i ``in` `range``(M):`   `        ``# Travel from edg[i][0]` `        ``# to edg[i][1]` `        ``adj[edg[i][``0``]``-``1``].append(edg[i][``1``]``-``1``)`   `    ``# dp table initialized with -1` `    ``# indicating not visited` `    ``dp ``=` `[[``-``1` `for` `i ``in` `range``(N)] ``for` `j ``in` `range``(``1001``)]`   `    ``# Base case` `    ``dp[``0``][``0``] ``=` `0`   `    ``ans ``=` `0`   `    ``# Simulating time from 0 to 1000` `    ``for` `curTime ``in` `range``(``1000``):`   `        ``# At each unit time iterate` `        ``# on each node` `        ``for` `i ``in` `range``(N):`   `            ``# If dp[d][i] == -1 then the` `            ``# node can't be visited` `            ``if` `dp[curTime][i] !``=` `-``1``:` `                ``for` `u ``in` `adj[i]:`   `                    ``# dp[curTime + 1][u]` `                    ``# is max(current coins` `                    ``# earned, previous` `                    ``# node's earnings +` `                    ``# current node's` `                    ``# earnings)` `                    ``dp[curTime ``+` `1``][u] ``=` `max``(dp[curTime ``+` `1``]` `                                             ``[u], dp[curTime][i] ``+` `A[u])`   `        ``ans ``=` `max``(ans, (dp[curTime][``0``] ``-` `(C ``*` `curTime ``*` `curTime)))`   `    ``print``(ans)`     `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:`   `    ``# Input 1` `    ``A ``=` `[``0``, ``10``, ``20``]` `    ``edges ``=` `[[``1``, ``2``], [``2``, ``3``], [``3``, ``1``]]` `    ``C ``=` `1` `    ``N ``=` `len``(A)` `    ``M ``=` `3`   `    ``# Function Call` `    ``maximumCoins(A, N, edges, M, C)`   `    ``# Input 2` `    ``A1 ``=` `[``0``, ``10``, ``20``]` `    ``edges1 ``=` `[[``1``, ``2``], [``2``, ``3``], [``3``, ``1``]]` `    ``C1 ``=` `10` `    ``N1 ``=` `len``(A1)` `    ``M1 ``=` `3`   `    ``# Function Call` `    ``maximumCoins(A1, N1, edges1, M1, C1)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Program {` `    ``// Function to calculate maximum coins during trips` `    ``public` `static` `void` `    ``maximumCoins(``int``[] A, ``int` `N, ``int``[][] edg, ``int` `M, ``int` `C)` `    ``{`   `        ``// Adjacency list` `        ``List > adj = ``new` `List >();` `        ``for` `(``int` `i = 0; i < N; i++) {` `            ``adj.Add(``new` `List<``int``>());` `        ``}`   `        ``for` `(``int` `i = 0; i < M; i++) {`   `            ``// Travel from edg[i][0] to edg[i][1]` `            ``adj[edg[i][0] - 1].Add(edg[i][1] - 1);` `        ``}`   `        ``// dp table initialized with -1 indicating not` `        ``// visited` `        ``int``[][] dp = ``new` `int``[1001][];` `        ``for` `(``int` `i = 0; i < 1001; i++) {` `            ``dp[i] = ``new` `int``[N];` `            ``for` `(``int` `j = 0; j < N; j++) {` `                ``dp[i][j] = -1;` `            ``}` `        ``}`   `        ``// Base case` `        ``dp[0][0] = 0;`   `        ``int` `ans = 0;`   `        ``// Simulating time from 0 to 1000` `        ``for` `(``int` `curTime = 0; curTime < 1000; curTime++) {`   `            ``// At each unit time iterate on each node` `            ``for` `(``int` `i = 0; i < N; i++) {`   `                ``// If dp[d][i] == -1 then the node can't be` `                ``// visited` `                ``if` `(dp[curTime][i] != -1) {` `                    ``foreach``(``int` `u ``in` `adj[i])` `                    ``{`   `                        ``// dp[curTime + 1][u] is max(current` `                        ``// coins earned, previous node's` `                        ``// earnings + current node's` `                        ``// earnings)` `                        ``dp[curTime + 1][u] = Math.Max(` `                            ``dp[curTime + 1][u],` `                            ``dp[curTime][i] + A[u]);` `                    ``}` `                ``}` `            ``}` `            ``ans = Math.Max(` `                ``ans,` `                ``(dp[curTime][0] - (C * curTime * curTime)));` `        ``}`   `        ``Console.WriteLine(ans);` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{`   `        ``// Input 1` `        ``int``[] A = { 0, 10, 20 };` `        ``int``[][] edges` `            ``= { ``new` `int``[] { 1, 2 }, ``new` `int``[] { 2, 3 },` `                ``new` `int``[] { 3, 1 } };` `        ``int` `C = 1;` `        ``int` `N = A.Length;` `        ``int` `M = 3;`   `        ``// Function Call` `        ``maximumCoins(A, N, edges, M, C);`   `        ``// Input 2` `        ``int``[] A1 = { 0, 10, 20 };` `        ``int``[][] edges1` `            ``= { ``new` `int``[] { 1, 2 }, ``new` `int``[] { 2, 3 },` `                ``new` `int``[] { 3, 1 } };` `        ``int` `C1 = 10;` `        ``int` `N1 = A1.Length;` `        ``int` `M1 = 3;`   `        ``// Function Call` `        ``maximumCoins(A1, N1, edges1, M1, C1);` `    ``}` `}`   `// This code is contributed by Tapesh(tapeshdua420)`

## Javascript

 `// Function to calculate maximum coins during trips` `function` `maximumCoins(A, N, edg, M, C) {` `    ``// Adjacency list` `let adj = [];` `for` `(let i = 0; i < N; i++) {` `    ``adj.push([]);` `}`   `for` `(let i = 0; i < M; i++) {` `    ``// Travel from edg[i][0] to edg[i][1]` `    ``adj[edg[i][0] - 1].push(edg[i][1] - 1);` `}`   `// dp table initialized with -1 indicating not visited` `let dp = [];` `for` `(let i = 0; i < 1001; i++) {` `    ``let temp = [];` `    ``for` `(let j = 0; j < N; j++) {` `        ``temp.push(-1);` `    ``}` `    ``dp.push(temp);` `}`   `// Base case` `dp[0][0] = 0;`   `let ans = 0;`   `// Simulating time from 0 to 1000` `for` `(let curTime = 0; curTime < 1000; curTime++) {`   `    ``// At each unit time iterate on each node` `    ``for` `(let i = 0; i < N; i++) {`   `        ``// If dp[d][i] == -1 then the node can't be visited` `        ``if` `(dp[curTime][i] != -1) {` `            ``for` `(let j = 0; j < adj[i].length; j++) {`   `                ``let u = adj[i][j];`   `                ``// dp[curTime + 1][u] is max(current coins earned, previous` `                ``// node's earnings + current node's earnings)` `                ``dp[curTime + 1][u] = Math.max(dp[curTime + 1][u], dp[curTime][i] + A[u]);` `            ``}` `        ``}` `    ``}`   `    ``ans = Math.max(ans, (dp[curTime][0] - (C * curTime * curTime)));` `}`   `console.log(ans);` `}`   `// Driver Code` `let A = [0, 10, 20];` `let edges = [[1, 2], [2, 3], [3, 1]];` `let C = 1;` `let N = A.length;` `let M = 3;`   `// Function Call` `maximumCoins(A, N, edges, M, C);`   `let A1 = [0, 10, 20];` `let edges1 = [[1, 2], [2, 3], [3, 1]];` `let C1 = 10;` `let N1 = A1.length;` `let M1 = 3;`   `// Function Call` `maximumCoins(A1, N1, edges1, M1, C1);`

Output

```24
0```

Time Complexity: O((N + M) * D)
Auxiliary Space: O(N * D) where D is the maximum number of nodes visited.

Related Articles:

My Personal Notes arrow_drop_up