 Open in App
Not now

# Maximum cost path in an Undirected Graph such that no edge is visited twice in a row

• Difficulty Level : Hard
• Last Updated : 24 Nov, 2021

Given an undirected graph having N vertices and M edges and each vertex is associated with a cost and a source vertex S is given. The task is to find the maximum cost path from source vertex S such that no edge is visited consecutively 2 or more times.

Examples:

Input: N = 5, M = 5, source = 1, cost[] = {2, 2, 8, 6, 9}, Below is the given graph: Output: 21
Explanation:
The maximum cost path matrix is given as:
1 -> 2 -> 0 -> 1 -> 4
Cost = 2 + 8 + 2 + 2 + 9 = 21

Input: N = 8, M = 8, source = 3, cost[] = {10, 11, 4, 12, 3, 4, 7, 9} Output: 46

Explanation:
The maximum cost path matrix is given as:
3 -> 0 -> 2 -> 1 -> 7

Approach: The idea is to check if there exists a loop exists in the graph, then all vertices of the loop need to be traversed and then traverse graph towards the leaf nodes with the maximum cost. And if the loop does not exist then the problem statement converts to find maximum cost path in any directed graph.

Below are the declaration used in the program:

• dp[i]: stores the total cost to traverse the node ‘i’ and all it’s children node.
• vis[i]: marks the nodes which have been visited.
• canTake: stores the resultant sum of all node of maximum cost path excluding the leaf vertex and its children node, if it exists.
• best: stores the cost of a maximum cost leaf node and its children node(if it exists).
• check: boolean variable used as a flag to find a loop in the graph, its value changes to 0 when the loop is found.

Below are the steps:

1. Perform DFS traversal with flag variable check set to ‘1’ initially denoting no loop found.
2. Simultaneously build the dp[] for each node with the maximum cost updated till that traversed node.
3. If the adjacent node is found to be already visited and it is not the parent node then the loop is found and set the value of the check to 0.
4. Add the cost of all nodes of the loop to canTake.
5. After traversing adjacent nodes of the traversing node, no loop is found, then it represents the cost of the path leading from loop to leaf vertex and updates best to dp[i] if dp[i] is greater than best.
6. After traversal of the graph, print the sum of canTake and best.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach` `#include ` `using` `namespace` `std;`   `// To store the resulting` `// sum of the cost` `int` `canTake;`   `// To store largest` `// cost leaf vertex` `int` `best;`   `vector<``int``> dp;` `vector<``bool``> vis;`   `// DFS Traversal to find the update` `// the maximum cost of from any` `// node to leaf` `int` `dfs(vector >& g,` `        ``int``* cost, ``int` `u, ``int` `pre)` `{`   `    ``// Mark vertex as visited` `    ``vis[u] = ``true``;`   `    ``// Store vertex initial cost` `    ``dp[u] = cost[u];`   `    ``// Initially assuming edge` `    ``// not to be traversed` `    ``bool` `check = 1;`   `    ``int` `cur = cost[u];` `    ``for` `(``auto``& x : g[u]) {`   `        ``// Back edge found so,` `        ``// edge can be part of` `        ``// traversal` `        ``if` `(vis[x] && x != pre) {` `            ``check = 0;` `        ``}`   `        ``// New vertex is found` `        ``else` `if` `(!vis[x]) {`   `            ``// Bitwise AND the current` `            ``// check with the returned` `            ``// check by the previous` `            ``// DFS Call` `            ``check &= dfs(g, cost, x, u);`   `            ``// Adds parent and its` `            ``// children cost` `            ``cur = max(cur,` `                      ``cost[u] + dp[x]);` `        ``}` `    ``}`   `    ``// Updates total cost of parent` `    ``// including child nodes` `    ``dp[u] = cur;`   `    ``// Edge is part of the cycle` `    ``if` `(!check) {`   `        ``// Add cost of vertex` `        ``// to the answer` `        ``canTake += cost[u];` `    ``}` `    ``else` `{`   `        ``// Updates the largest` `        ``// cost leaf vertex` `        ``best = max(best, dp[u]);` `    ``}`   `    ``return` `check;` `}`   `// Function to find the maximum cost` `// from source vertex such that no` `// two edges is traversed twice` `int` `FindMaxCost(vector >& g,` `                ``int``* cost, ``int` `source)` `{` `    ``// DFS Call` `    ``dfs(g, cost, source, -1);`   `    ``// Print the maximum cost` `    ``cout << canTake + best;` `}`   `// Driver Code` `int` `main()` `{` `    ``int` `n = 5, m = 5;` `    ``dp.resize(n+1);` `      ``vis.resize(n+1);` `    ``// Cost Array` `    ``int` `cost[] = { 2, 2, 8, 6, 9 };`   `    ``vector > g(n);`   `    ``// Given Graph` `    ``g.push_back(1);` `    ``g.push_back(0);` `    ``g.push_back(2);` `    ``g.push_back(0);` `    ``g.push_back(3);` `    ``g.push_back(0);` `    ``g.push_back(2);` `    ``g.push_back(1);` `    ``g.push_back(4);` `    ``g.push_back(1);`   `    ``// Given Source Node` `    ``int` `source = 1;`   `    ``// Function Call` `    ``FindMaxCost(g, cost, source);` `    ``return` `0;` `}`

## Java

 `// Java program for the above approach` `import` `java.util.*;`   `class` `GFG{` `    `  `static` `int` `N = ``100000``;`   `// To store the resulting` `// sum of the cost` `static` `int` `canTake;`   `// To store largest` `// cost leaf vertex` `static` `int` `best;`   `static` `int` `[]dp = ``new` `int``[N];` `static` `boolean` `[]vis = ``new` `boolean``[N];`   `// DFS Traversal to find the update` `// the maximum cost of from any` `// node to leaf` `static` `boolean` `dfs(Vector []g,` `                   ``int` `[]cost, ``int` `u, ``int` `pre)` `{` `    `  `    ``// Mark vertex as visited` `    ``vis[u] = ``true``;`   `    ``// Store vertex initial cost` `    ``dp[u] = cost[u];`   `    ``// Initially assuming edge` `    ``// not to be traversed` `    ``boolean` `check = ``true``;`   `    ``int` `cur = cost[u];` `    ``for``(``int` `x : g[u])` `    ``{` `        `  `        ``// Back edge found so,` `        ``// edge can be part of` `        ``// traversal` `        ``if` `(vis[x] && x != pre)` `        ``{` `            ``check = ``false``;` `        ``}`   `        ``// New vertex is found` `        ``else` `if` `(!vis[x]) ` `        ``{`   `            ``// Bitwise AND the current` `            ``// check with the returned` `            ``// check by the previous` `            ``// DFS Call` `            ``check = dfs(g, cost, x, u) ? ` `                    ``false` `: ``true``;`   `            ``// Adds parent and its` `            ``// children cost` `            ``cur = Math.max(cur, cost[u] +` `                                  ``dp[x]);` `        ``}` `    ``}`   `    ``// Updates total cost of parent` `    ``// including child nodes` `    ``dp[u] = cur;`   `    ``// Edge is part of the cycle` `    ``if` `(!check) ` `    ``{`   `        ``// Add cost of vertex` `        ``// to the answer` `        ``canTake += cost[u];` `    ``}` `    ``else` `    ``{`   `        ``// Updates the largest` `        ``// cost leaf vertex` `        ``best = Math.max(best, dp[u]);` `    ``}` `    ``return` `check;` `}`   `// Function to find the maximum cost` `// from source vertex such that no` `// two edges is traversed twice` `static` `void` `FindMaxCost(Vector [] g,` `                        ``int` `[]cost, ``int` `source)` `{` `    `  `    ``// DFS call` `    ``dfs(g, cost, source, -``1``);`   `    ``// Print the maximum cost` `    ``System.out.print(canTake + best);` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    ``int` `n = ``5``, m = ``5``;`   `    ``// Cost Array` `    ``int` `cost[] = { ``2``, ``2``, ``8``, ``6``, ``9` `};` `    `  `    ``@SuppressWarnings``(``"unchecked"``)` `    ``Vector []g = ``new` `Vector[n];` `    ``for``(``int` `i = ``0``; i < g.length; i++)` `        ``g[i] = ``new` `Vector();` `        `  `    ``// Given Graph` `    ``g[``0``].add(``1``);` `    ``g[``1``].add(``0``);` `    ``g[``0``].add(``2``);` `    ``g[``2``].add(``0``);` `    ``g[``0``].add(``3``);` `    ``g[``3``].add(``0``);` `    ``g[``1``].add(``2``);` `    ``g[``2``].add(``1``);` `    ``g[``1``].add(``4``);` `    ``g[``4``].add(``1``);`   `    ``// Given Source Node` `    ``int` `source = ``1``;`   `    ``// Function call` `    ``FindMaxCost(g, cost, source);` `}` `}`   `// This code is contributed by Amit Katiyar`

## Python3

 `# Python3 program for the above approach` `N ``=` `100000` ` `  `# To store the resulting` `# sum of the cost` `canTake ``=` `0` ` `  `# To store largest` `# cost leaf vertex` `best ``=` `0` ` `  `dp ``=` `[``0` `for` `i ``in` `range``(N)]` `vis ``=` `[``0` `for` `i ``in` `range``(N)]` ` `  `# DFS Traversal to find the update` `# the maximum cost of from any` `# node to leaf` `def` `dfs(g, cost, u, pre):` `    `  `    ``global` `canTake, best` `    `  `    ``# Mark vertex as visited` `    ``vis[u] ``=` `True` ` `  `    ``# Store vertex initial cost` `    ``dp[u] ``=` `cost[u]` ` `  `    ``# Initially assuming edge` `    ``# not to be traversed` `    ``check ``=` `1` ` `  `    ``cur ``=` `cost[u]` `    `  `    ``for` `x ``in` `g[u]:` ` `  `        ``# Back edge found so,` `        ``# edge can be part of` `        ``# traversal` `        ``if` `(vis[x] ``and` `x !``=` `pre):` `            ``check ``=` `0` `            `  `        ``# New vertex is found` `        ``elif` `(``not` `vis[x]):` ` `  `            ``# Bitwise AND the current` `            ``# check with the returned` `            ``# check by the previous` `            ``# DFS Call` `            ``check &``=` `dfs(g, cost, x, u)` ` `  `            ``# Adds parent and its` `            ``# children cost` `            ``cur ``=` `max``(cur, cost[u] ``+` `dp[x])` ` `  `    ``# Updates total cost of parent` `    ``# including child nodes` `    ``dp[u] ``=` `cur` ` `  `    ``# Edge is part of the cycle` `    ``if` `(``not` `check):` ` `  `        ``# Add cost of vertex` `        ``# to the answer` `        ``canTake ``+``=` `cost[u]` `    `  `    ``else``:` ` `  `        ``# Updates the largest` `        ``# cost leaf vertex` `        ``best ``=` `max``(best, dp[u])` `    `  `    ``return` `check` ` `  `# Function to find the maximum cost` `# from source vertex such that no` `# two edges is traversed twice` `def` `FindMaxCost(g, cost, source):` `  `  `    ``# DFS Call` `    ``dfs(g, cost, source, ``-``1``)` ` `  `    ``# Print the maximum cost` `    ``print``(canTake ``+` `best)` `    `  `# Driver Code` `if` `__name__``=``=``'__main__'``:` `  `  `    ``n ``=` `5` `    ``m ``=` `5` ` `  `    ``# Cost Array` `    ``cost ``=` `[ ``2``, ``2``, ``8``, ``6``, ``9` `]` ` `  `    ``g ``=` `[[] ``for` `i ``in` `range``(n)]` ` `  `    ``# Given Graph` `    ``g[``0``].append(``1``)` `    ``g[``1``].append(``0``)` `    ``g[``0``].append(``2``)` `    ``g[``2``].append(``0``)` `    ``g[``0``].append(``3``)` `    ``g[``3``].append(``0``)` `    ``g[``1``].append(``2``)` `    ``g[``2``].append(``1``)` `    ``g[``1``].append(``4``)` `    ``g[``4``].append(``1``)` ` `  `    ``# Given Source Node` `    ``source ``=` `1` ` `  `    ``# Function Call` `    ``FindMaxCost(g, cost, source)` `    `  `# This code is contributed by rutvik_56`

## C#

 `// C# program for ` `// the above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{` `    `  `static` `int` `N = 100000;`   `// To store the resulting` `// sum of the cost` `static` `int` `canTake;`   `// To store largest` `// cost leaf vertex` `static` `int` `best;`   `static` `int` `[]dp = ``new` `int``[N];` `static` `bool` `[]vis = ``new` `bool``[N];`   `// DFS Traversal to find the update` `// the maximum cost of from any` `// node to leaf` `static` `bool` `dfs(List<``int``> []g, ` `                ``int` `[]cost, ` `                ``int` `u, ``int` `pre)` `{` `  ``// Mark vertex as visited` `  ``vis[u] = ``true``;`   `  ``// Store vertex initial cost` `  ``dp[u] = cost[u];`   `  ``// Initially assuming edge` `  ``// not to be traversed` `  ``bool` `check = ``true``;`   `  ``int` `cur = cost[u];` `  ``foreach``(``int` `x ``in` `g[u])` `  ``{` `    ``// Back edge found so,` `    ``// edge can be part of` `    ``// traversal` `    ``if` `(vis[x] && x != pre)` `    ``{` `      ``check = ``false``;` `    ``}`   `    ``// New vertex is found` `    ``else` `if` `(!vis[x]) ` `    ``{` `      ``// Bitwise AND the current` `      ``// check with the returned` `      ``// check by the previous` `      ``// DFS Call` `      ``check = dfs(g, cost, x, u) ? ` `              ``false` `: ``true``;`   `      ``// Adds parent and its` `      ``// children cost` `      ``cur = Math.Max(cur, cost[u] + dp[x]);` `    ``}` `  ``}`   `  ``// Updates total cost of parent` `  ``// including child nodes` `  ``dp[u] = cur;`   `  ``// Edge is part of the cycle` `  ``if` `(!check) ` `  ``{` `    ``// Add cost of vertex` `    ``// to the answer` `    ``canTake += cost[u];` `  ``}` `  ``else` `  ``{` `    ``// Updates the largest` `    ``// cost leaf vertex` `    ``best = Math.Max(best, dp[u]);` `  ``}` `  ``return` `check;` `}`   `// Function to find the maximum cost` `// from source vertex such that no` `// two edges is traversed twice` `static` `void` `FindMaxCost(List<``int``> [] g,` `                        ``int` `[]cost, ``int` `source)` `{` `  ``// DFS call` `  ``dfs(g, cost, source, -1);`   `  ``// Print the maximum cost` `  ``Console.Write(canTake + best);` `}`   `// Driver Code` `public` `static` `void` `Main(String[] args)` `{` `  ``int` `n = 5, m = 5;`   `  ``// Cost Array` `  ``int` `[]cost = {2, 2, 8, 6, 9};`   `  ``List<``int``> []g = ``new` `List<``int``>[n];` `  `  `  ``for``(``int` `i = 0; i < g.Length; i++)` `    ``g[i] = ``new` `List<``int``>();`   `  ``// Given Graph` `  ``g.Add(1);` `  ``g.Add(0);` `  ``g.Add(2);` `  ``g.Add(0);` `  ``g.Add(3);` `  ``g.Add(0);` `  ``g.Add(2);` `  ``g.Add(1);` `  ``g.Add(4);` `  ``g.Add(1);`   `  ``// Given Source Node` `  ``int` `source = 1;`   `  ``// Function call` `  ``FindMaxCost(g, cost, source);` `}` `}`   `// This code is contributed by Princi Singh`

## Javascript

 ``

Output:

`21`

Time Complexity: O(N + M) where N is a number of vertices and M is the number of edges.
Auxiliary Space: O(N + M) where N is a number of vertices and M is a number of edges.

My Personal Notes arrow_drop_up
Related Articles