Find the largest sum of a cycle in the maze
Last Updated :
27 Mar, 2024
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)
Time Complexity: O(n).
Auxiliary Space: O(n).
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...