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

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: 
Perform DFS traversal with flag variable check set to ‘1’ initially denoting no loop found.Simultaneously build the dp[] for each node with the maximum cost updated till that traversed node.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.Add the cost of all nodes of the loop to canTake.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.After traversal of the graph, print the sum of canTake and best.
Perform DFS traversal with flag variable check set to ‘1’ initially denoting no loop found.
Simultaneously build the dp[] for each node with the maximum cost updated till that traversed node.
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.
Add the cost of all nodes of the loop to canTake.
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.
After traversal of the graph, print the sum of canTake and best.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // To store the resulting// sum of the costint canTake; // To store largest// cost leaf vertexint best; vector<int> dp;vector<bool> vis; // DFS Traversal to find the update// the maximum cost of from any// node to leafint dfs(vector<vector<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 = 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 twiceint FindMaxCost(vector<vector<int> >& g,                int* cost, int source){    // DFS Call    dfs(g, cost, source, -1);     // Print the maximum cost    cout << canTake + best;} // Driver Codeint main(){    int n = 5, m = 5;    dp.resize(n+1);      vis.resize(n+1);    // Cost Array    int cost[] = { 2, 2, 8, 6, 9 };     vector<vector<int> > g(n);     // Given Graph    g[0].push_back(1);    g[1].push_back(0);    g[0].push_back(2);    g[2].push_back(0);    g[0].push_back(3);    g[3].push_back(0);    g[1].push_back(2);    g[2].push_back(1);    g[1].push_back(4);    g[4].push_back(1);     // Given Source Node    int source = 1;     // Function Call    FindMaxCost(g, cost, source);    return 0;}
// Java program for the above approachimport java.util.*; class GFG{     static int N = 100000; // To store the resulting// sum of the coststatic int canTake; // To store largest// cost leaf vertexstatic 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 leafstatic boolean dfs(Vector<Integer> []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 twicestatic void FindMaxCost(Vector<Integer> [] g,                        int []cost, int source){         // DFS call    dfs(g, cost, source, -1);     // Print the maximum cost    System.out.print(canTake + best);} // Driver Codepublic static void main(String[] args){    int n = 5, m = 5;     // Cost Array    int cost[] = { 2, 2, 8, 6, 9 };         @SuppressWarnings("unchecked")    Vector<Integer> []g = new Vector[n];    for(int i = 0; i < g.length; i++)        g[i] = new Vector<Integer>();             // 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 program for the above approachN = 100000  # To store the resulting# sum of the costcanTake = 0  # To store largest# cost leaf vertexbest = 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 leafdef 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 twicedef FindMaxCost(g, cost, source):       # DFS Call    dfs(g, cost, source, -1)      # Print the maximum cost    print(canTake + best)     # Driver Codeif __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# program for// the above approachusing System;using System.Collections.Generic;class GFG{     static int N = 100000; // To store the resulting// sum of the coststatic int canTake; // To store largest// cost leaf vertexstatic 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 leafstatic 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 twicestatic 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 Codepublic 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[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 Princi Singh
<script> // Javascript program for// the above approach     var N = 100000; // To store the resulting// sum of the costvar canTake = 0; // To store largest// cost leaf vertexvar best = 0; var dp = Array(N).fill(0);var vis = Array(N).fill(false); // DFS Traversal to find the update// the maximum cost of from any// node to leaffunction dfs(g, cost, u, pre){  // Mark vertex as visited  vis[u] = true;   // Store vertex initial cost  dp[u] = cost[u];   // Initially assuming edge  // not to be traversed  var check = true;   var cur = cost[u];  for(var x of 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)  {    // push 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 twicefunction FindMaxCost(g, cost, source){  // DFS call  dfs(g, cost, source, -1);   // Print the maximum cost  document.write(canTake + best);} // Driver Codevar n = 5, m = 5;// Cost Arrayvar cost = [2, 2, 8, 6, 9];var g = Array.from(Array(n), ()=>Array()); // Given Graphg[0].push(1);g[1].push(0);g[0].push(2);g[2].push(0);g[0].push(3);g[3].push(0);g[1].push(2);g[2].push(1);g[1].push(4);g[4].push(1);// Given Source Nodevar source = 1;// Function callFindMaxCost(g, cost, source); </script>
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. 
nidhi_biet
amit143katiyar
princi singh
rutvik_56
noob2000
ashutoshsinghgeeksforgeeks
Algorithms-Graph Traversals
DFS
Algorithms
Arrays
Dynamic Programming
Graph
Greedy
Recursion
Arrays
Dynamic Programming
Greedy
Recursion
DFS
Graph
Algorithms
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
What is Hashing | A Complete Tutorial
Find if there is a path between two vertices in an undirected graph
How to Start Learning DSA?
Complete Roadmap To Learn DSA From Scratch
Types of Complexity Classes | P, NP, CoNP, NP hard and NP complete
Arrays in Java
Write a program to reverse an array or string
Maximum and minimum of an array using minimum number of comparisons
Largest Sum Contiguous Subarray
Arrays in C/C++