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 = 21Input: 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.
Below is the implementation of the above approach:
C++
| // C++ program for the above approach#include <bits/stdc++.h>usingnamespacestd;// To store the resulting// sum of the costintcanTake;// To store largest// cost leaf vertexintbest;vector<int> dp;vector<bool> vis;// DFS Traversal to find the update// the maximum cost of from any// node to leafintdfs(vector<vector<int> >& g,        int* cost, intu, intpre){    // Mark vertex as visited    vis[u] = true;    // Store vertex initial cost    dp[u] = cost[u];    // Initially assuming edge    // not to be traversed    boolcheck = 1;    intcur = 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        elseif(!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]);    }    returncheck;}// Function to find the maximum cost// from source vertex such that no// two edges is traversed twiceintFindMaxCost(vector<vector<int> >& g,                int* cost, intsource){    // DFS Call    dfs(g, cost, source, -1);    // Print the maximum cost    cout << canTake + best;}// Driver Codeintmain(){    intn = 5, m = 5;    dp.resize(n+1);      vis.resize(n+1);    // Cost Array    intcost[] = { 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    intsource = 1;    // Function Call    FindMaxCost(g, cost, source);    return0;} | 
Java
| // Java program for the above approachimportjava.util.*;classGFG{    staticintN = 100000;// To store the resulting// sum of the coststaticintcanTake;// To store largest// cost leaf vertexstaticintbest;staticint[]dp = newint[N];staticboolean[]vis = newboolean[N];// DFS Traversal to find the update// the maximum cost of from any// node to leafstaticbooleandfs(Vector<Integer> []g,                   int[]cost, intu, intpre){        // Mark vertex as visited    vis[u] = true;    // Store vertex initial cost    dp[u] = cost[u];    // Initially assuming edge    // not to be traversed    booleancheck = true;    intcur = cost[u];    for(intx : g[u])    {                // Back edge found so,        // edge can be part of        // traversal        if(vis[x] && x != pre)        {            check = false;        }        // New vertex is found        elseif(!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]);    }    returncheck;}// Function to find the maximum cost// from source vertex such that no// two edges is traversed twicestaticvoidFindMaxCost(Vector<Integer> [] g,                        int[]cost, intsource){        // DFS call    dfs(g, cost, source, -1);    // Print the maximum cost    System.out.print(canTake + best);}// Driver Codepublicstaticvoidmain(String[] args){    intn = 5, m = 5;    // Cost Array    intcost[] = { 2, 2, 8, 6, 9};        @SuppressWarnings("unchecked")    Vector<Integer> []g = newVector[n];    for(inti = 0; i < g.length; i++)        g[i] = newVector<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    intsource = 1;    // Function call    FindMaxCost(g, cost, source);}}// This code is contributed by Amit Katiyar | 
Python3
| # Python3 program for the above approachN =100000 # To store the resulting# sum of the costcanTake =0 # To store largest# cost leaf vertexbest =0 dp =[0fori inrange(N)]vis =[0fori inrange(N)] # DFS Traversal to find the update# the maximum cost of from any# node to leafdefdfs(g, cost, u, pre):        globalcanTake, 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]        forx ing[u]:         # Back edge found so,        # edge can be part of        # traversal        if(vis[x] andx !=pre):            check =0                    # New vertex is found        elif(notvis[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(notcheck):         # Add cost of vertex        # to the answer        canTake +=cost[u]        else:         # Updates the largest        # cost leaf vertex        best =max(best, dp[u])        returncheck # Function to find the maximum cost# from source vertex such that no# two edges is traversed twicedefFindMaxCost(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 =[[] fori inrange(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 approachusingSystem;usingSystem.Collections.Generic;classGFG{    staticintN = 100000;// To store the resulting// sum of the coststaticintcanTake;// To store largest// cost leaf vertexstaticintbest;staticint[]dp = newint[N];staticbool[]vis = newbool[N];// DFS Traversal to find the update// the maximum cost of from any// node to leafstaticbooldfs(List<int> []g,                 int[]cost,                 intu, intpre){  // Mark vertex as visited  vis[u] = true;  // Store vertex initial cost  dp[u] = cost[u];  // Initially assuming edge  // not to be traversed  boolcheck = true;  intcur = cost[u];  foreach(intx ing[u])  {    // Back edge found so,    // edge can be part of    // traversal    if(vis[x] && x != pre)    {      check = false;    }    // New vertex is found    elseif(!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]);  }  returncheck;}// Function to find the maximum cost// from source vertex such that no// two edges is traversed twicestaticvoidFindMaxCost(List<int> [] g,                        int[]cost, intsource){  // DFS call  dfs(g, cost, source, -1);  // Print the maximum cost  Console.Write(canTake + best);}// Driver CodepublicstaticvoidMain(String[] args){  intn = 5, m = 5;  // Cost Array  int[]cost = {2, 2, 8, 6, 9};  List<int> []g = newList<int>[n];    for(inti = 0; i < g.Length; i++)    g[i] = newList<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  intsource = 1;  // Function call  FindMaxCost(g, cost, source);}}// This code is contributed by Princi Singh | 
Javascript
| <script>// Javascript program for // the above approach    varN = 100000;// To store the resulting// sum of the costvarcanTake = 0;// To store largest// cost leaf vertexvarbest = 0;vardp = Array(N).fill(0);varvis = Array(N).fill(false);// DFS Traversal to find the update// the maximum cost of from any// node to leaffunctiondfs(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  varcheck = true;  varcur = cost[u];  for(varx of g[u])  {    // Back edge found so,    // edge can be part of    // traversal    if(vis[x] && x != pre)    {      check = false;    }    // New vertex is found    elseif(!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]);  }  returncheck;}// Function to find the maximum cost// from source vertex such that no// two edges is traversed twicefunctionFindMaxCost(g, cost, source){  // DFS call  dfs(g, cost, source, -1);  // Print the maximum cost  document.write(canTake + best);}// Driver Codevarn = 5, m = 5;// Cost Arrayvarcost = [2, 2, 8, 6, 9];varg = 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 Nodevarsource = 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. 
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    








