Open In App

Find the largest sum of a cycle in the maze

Last Updated : 27 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given a maze with N cells. Each cell may have multiple entry points but not more than one exit(i.e entry/exit points are unidirectional doors like valves).
You are given an array Edge[] of N integers, where Edge[i] contains the cell number that can be reached from of cell i in one step. Edge[i] is -1 if the ith cell doesn’t have an exit. 
The task is to find the largest sum of a cycle in the maze(Sum of a cycle is the sum of the cell indexes of all cells present in that cycle).

Note: The cells are named with an integer value from 0 to N-1. If there is no cycle in the graph then return -1.

Examples:

Input: N = 4, Edge[] = {1, 2, 0, -1}
Output: 3
Explanation: There is only one cycle in the graph. (i.e 0 -> 1 -> 2 -> 0) Sum of the cell index in that cycle = 0 + 1 + 2 = 3.

Input: N = 4, Edge[] = {2, 0, -1, 2}
Output: -1
Explanation: 1 -> 0 -> 2 <- 3
There is no cycle in the graph.

Approach: To solve the problem follow the below idea:

In order to solve this problem, we will use Depth First Search.

  • First we will construct the graph, with the given nodes and edges. 
  • Now for every node, if the node is not visited we will try to find if the node is a part of a cycle or not. 
  • If it is, we will mark all the nodes as visited and calculate the sum of the path. 
  • Thus we can find out largest sum cycle.

Below is the steps for above approach:

  • Initialize a 2D vector v that will store the edges of a graph, and three vectors vis, par, and tmp of integer type to keep track of visited nodes, parent nodes, and temporary nodes respectively.
  • Create a function largestSumCycle that takes an integer N and a vector Edge and returns the largest sum of nodes in a cycle.
  • Initialize ans to -1, vis that will store visited nodes, v that will store graph edges, and par vectors that will store parent nodes.
  • Populate the graph edges by adding an edge from i to Edge[i] if Edge[i] is not -1.
  • Iterate through all nodes of the graph. If a node is unvisited, call the dfs function on it and update ans if a cycle with a larger sum is found.
  • Create a recursive function dfs that takes a node and its parent as input and returns the sum of nodes in the cycle (if found), else it returns -1.
  • In the dfs function:
    • Mark the current node as visited, store its parent node, and push it to the temporary vector.
      • vis[node] = 1, par[node] = p, tmp.push_back(node).
  • For each adjacent node i of the current node, if i is not visited, recursively call the dfs function on node i with the current node node as the parent node. If the returned value is not -1, return that value.
  • If i is visited and its status is 1 that means it is part of the current DFS path, then a cycle is detected. Calculate and return the sum of nodes in the cycle else, continue to the next adjacent node.
  • Mark all visited nodes as 2 and clear the temp vector.
  • Return ans as the largest sum of nodes in a cycle.

Below is the implementation of the above approach:

C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;

vector<vector<int> > v;
vector<int> vis, par, tmp;
long long dfs(int node, int p = -1)
{
    vis[node] = 1;
    par[node] = p;
    tmp.push_back(node);
    for (auto i : v[node]) {
        if (vis[i] == 0) {
            long long z = dfs(i, node);
            if (z != -1) {
                return z;
            }
        }
        else if (vis[i] == 1) {
            long long sum = i;
            while (node != i) {
                sum += node;
                node = par[node];
            }
            if (node == i)
                return sum;
            return -1;
        }
    }
    return -1;
}

// Function to find largest sum cycle
long long largestSumCycle(int N, vector<int> Edge)
{
    long long ans = -1;
    vis = vector<int>(N);
    v = vector<vector<int> >(N);
    par = vector<int>(N);

    for (int i = 0; i < N; i++) {
        if (Edge[i] != -1) {
            v[i].push_back(Edge[i]);
        }
    }

    for (int i = 0; i < N; i++) {
        if (!vis[i]) {
            ans = max(ans, dfs(i));
            for (auto j : tmp) {
                vis[j] = 2;
            }
            tmp.clear();
        }
    }

    return ans;
}

// Drivers code
int main()
{

    int N = 4;
    vector<int> Edge = { 1, 2, 0, -1 };

    // Function Call
    int ans = largestSumCycle(N, Edge);
    cout << ans;
    return 0;
}
Java
// Java code for the approach

import java.util.*;

public class GFG {
    // adjacency list
    static List<List<Integer> > adj = new ArrayList<>();
    // arrays for tracking visited nodes and their parent
    // nodes
    static int[] vis, par;
    // temporary list for storing nodes in a cycle
    static List<Integer> tmp = new ArrayList<>();

    // DFS function to find cycles and their sum
    static long dfs(int node, int p)
    {
        vis[node] = 1;
        par[node] = p;
        tmp.add(node);
        for (int i : adj.get(node)) {
            if (vis[i] == 0) {
                long z = dfs(i, node);
                if (z != -1) {
                    return z;
                }
            }
            else if (vis[i] == 1) {
                long sum = i;
                while (node != i) {
                    sum += node;
                    node = par[node];
                }
                if (node == i) {
                    return sum;
                }
                return -1;
            }
        }
        return -1;
    }

    // Function to find largest sum cycle
    static long largestSumCycle(int N, List<Integer> Edge)
    {
        long ans = -1;
        vis = new int[N];
        adj = new ArrayList<>(N);
        par = new int[N];

        // creating adjacency list
        for (int i = 0; i < N; i++) {
            adj.add(new ArrayList<>());
            if (Edge.get(i) != -1) {
                adj.get(i).add(Edge.get(i));
            }
        }

        // finding cycles and their sum using DFS
        for (int i = 0; i < N; i++) {
            if (vis[i] == 0) {
                ans = Math.max(ans, dfs(i, -1));
                for (int j : tmp) {
                    vis[j] = 2;
                }
                tmp.clear();
            }
        }

        return ans;
    }

    // Driver Code
    public static void main(String[] args)
    {
        int N = 4;
        List<Integer> Edge = Arrays.asList(1, 2, 0, -1);

        // Function Call
        long ans = largestSumCycle(N, Edge);
        System.out.println(ans);
    }
}
C#
using System;
using System.Collections.Generic;

class GFG {
    static List<List<int> > adj = new List<List<int> >();
    static int[] vis, par;
    static List<int> tmp = new List<int>();

    static long dfs(int node, int p = -1)
    {
        vis[node] = 1;
        par[node] = p;
        tmp.Add(node);
        foreach(int i in adj[node])
        {
            if (vis[i] == 0) {
                long z = dfs(i, node);
                if (z != -1) {
                    return z;
                }
            }
            else if (vis[i] == 1) {
                long sum = i;
                while (node != i) {
                    sum += node;
                    node = par[node];
                }
                if (node == i) {
                    return sum;
                }
                return -1;
            }
        }
        return -1;
    }

    static long largestSumCycle(int N, List<int> Edge)
    {
        long ans = -1;
        vis = new int[N];
        adj = new List<List<int> >(N);
        par = new int[N];

        for (int i = 0; i < N; i++) {
            adj.Add(new List<int>());
            if (Edge[i] != -1) {
                adj[i].Add(Edge[i]);
            }
        }

        for (int i = 0; i < N; i++) {
            if (vis[i] == 0) {
                ans = Math.Max(ans, dfs(i));
                foreach(int j in tmp) { vis[j] = 2; }
                tmp.Clear();
            }
        }

        return ans;
    }

    static void Main(string[] args)
    {
        int N = 4;
        List<int> Edge = new List<int>{ 1, 2, 0, -1 };

        // Function Call
        long ans = largestSumCycle(N, Edge);
        Console.WriteLine(ans);
    }
}
Javascript
// JavaScript code for the approach

// adjacency list
let adj = [];

// arrays for tracking visited nodes and their parent nodes
let vis, par;

// temporary list for storing nodes in a cycle
let tmp = [];

// DFS function to find cycles and their sum
function dfs(node, p) {
    vis[node] = 1;
    par[node] = p;
    tmp.push(node);
    for (let i of adj[node]) {
        if (vis[i] == 0) {
            let z = dfs(i, node);
            if (z != -1) {
                return z;
            }
        }
        else if (vis[i] == 1) {
            let sum = i;
            while (node != i) {
                sum += node;
                node = par[node];
            }
            if (node == i) {
                return sum;
            }
            return -1;
        }
    }
    return -1;
}

// Function to find largest sum cycle
function largestSumCycle(N, Edge) {
    let ans = -1;
    vis = new Array(N).fill(0);
    adj = new Array(N);

    // creating adjacency list
    for (let i = 0; i < N; i++) {
        adj[i] = [];
        if (Edge[i] != -1) {
            adj[i].push(Edge[i]);
        }
    }

    par = new Array(N);

    // finding cycles and their sum using DFS
    for (let i = 0; i < N; i++) {
        if (vis[i] == 0) {
            ans = Math.max(ans, dfs(i, -1));
            for (let j of tmp) {
                vis[j] = 2;
            }
            tmp = [];
        }
    }
    
    return ans;
}

// Driver Code
let N = 4;
let Edge = [1, 2, 0, -1];

// Function Call
let ans = largestSumCycle(N, Edge);
console.log(ans);
Python3
from typing import List

v = []
vis = []
par = []
tmp = []


def dfs(node: int, p: int = -1) -> int:
    vis[node] = 1
    par[node] = p
    tmp.append(node)
    for i in v[node]:
        if vis[i] == 0:
            z = dfs(i, node)
            if z != -1:
                return z
        elif vis[i] == 1:
            sum = i
            while node != i:
                sum += node
                node = par[node]
                if node == i:
                    return sum
            return -1
    return -1


def largestSumCycle(N: int, Edge: List[int]) -> int:
    ans = -1
    global v, vis, par, tmp
    vis = [0] * N
    v = [[] for _ in range(N)]
    par = [-1] * N
    for i in range(N):
        if Edge[i] != -1:
            v[i].append(Edge[i])

    for i in range(N):
        if not vis[i]:
            ans = max(ans, dfs(i))
            for j in tmp:
                vis[j] = 2
            tmp.clear()

    return ans


# Driver code
if __name__ == '__main__':
    N = 4
    Edge = [1, 2, 0, -1]
    # Function Call
    ans = largestSumCycle(N, Edge)
    print(ans)

Output
3

Time Complexity: O(n).
Auxiliary Space: O(n).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads