Find the number of sticks that forms cycle
Given N sticks with two sides Left and Right (represented by 0 and 1). Given 2d array, A[][4] of size M representing operations that have to be performed on these sticks in each operation {A, B, C, D} connect side B (Left or Right) of A’th stick with side D (Left or Right) of C’th stick. The task for this problem is to print a number of sticks that form a cycle.
Examples:
Input: N = 5, A[][4] = {{3, 0, 5, 1}, {5, 0, 3, 1}, {4, 0, 2, 1}}
Output: 1
Explanation: Given sticks have only one cycle between stick 3 and stick 5.Representation of example 1
Input: N = 7, A[][4] = {}
Output: 0
Approach: The following approach can be used to solve the given problem
Depth-First-Search can be used to solve this problem.
- Assuming each stick to be two nodes Left and Right Nodes which are already connected with each other.
- Do DFS() and keep track of previously visited nodes. While traversing if a given node is already visited and it is not the previous node then the cycle exists.
- Keep a counter that tracks the count of cycles.
Follow the steps below to solve the problem:
- Initialize flag with value 0.
- Create adjacency list adj[N + 1][2][2].
- Connect left and right nodes of the same stick by iterating on all N nodes.
- Performing all M operations by filling the adjacency list.
- Creating answer variable ans that is initialized with 0.
- Creating visited array vis[N + 1][2].
- Create a recursive function dfs() that contains two parameters one is the current node and another one is the previously visited node.
- iterating over all N nodes and calling dfs() function for each node.
- If an already visited node is visited and it is not the previous node update the flag to 1.
- At the end add a flag to ans and set the flag again back to zero for the next dfs call.
- Returning the ans variable.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // flag defined for detecting cycle int flag = 0; // dfs function void dfs(pair< int , int > v, pair< int , int > prev, vector<vector<vector<pair< int , int > > > >& adj, vector<vector< int > >& vis) { // marking current state visited vis[v.first][v.second] = 1; // travelling to neibours for ( auto & u : adj[v.first][v.second]) { // if not visited if (!vis[u.first][u.second]) { // call dfs function dfs(u, v, adj, vis); } // if visited else if (prev != u) { // mark flag 1 flag = 1; // return dfs return ; } } } // Function to count cycles formed by // sticks int countCycles( int N, int A[][4], int M) { // initializing adjaceny list vector<vector<vector<pair< int , int > > > > adj( N + 1, vector<vector<pair< int , int > > >(2)); // Left and Right of same sticks are // connected with each other for ( int i = 1; i <= N; i++) { adj[i][0].push_back({ i, 1 }); adj[i][1].push_back({ i, 0 }); } // performing all M operations for ( int i = 0; i < M; i++) { adj[A[i][0]][A[i][1]].push_back( { A[i][2], A[i][3] }); adj[A[i][2]][A[i][3]].push_back( { A[i][0], A[i][1] }); } // answer initialized with zero int ans = 0; // visited array vector<vector< int > > vis(N + 1, vector< int >(2, 0)); // calling all non visited nodes for ( int i = 1; i <= N; i++) { // if i is not visited if (!vis[i][0]) { // calling dfs function dfs({ i, 0 }, { -1, -1 }, adj, vis); // adding flag to answer ans += flag; // resetting flag to zero flag = 0; } } // return total cycles return ans; } // Driver Code int main() { // Input 1 int N = 5, A[][4] = { { 3, 0, 5, 1 }, { 5, 0, 3, 1 }, { 4, 0, 2, 1 } }; int M = 3; // Function Call cout << countCycles(N, A, M) << endl; // Input 2 int N1 = 5, A1[][4] = {}; int M1 = 0; // Function Call cout << countCycles(N1, A1, M1) << endl; return 0; } |
Java
// Java code to implement the approach import java.util.ArrayList; import java.util.List; public class GFG { // flag defined for detecting cycle static int flag = 0 ; // dfs function static void dfs( int [] v, int [] prev, List<List<List< int []> > > adj, int [][] vis) { // marking current state visited vis[v[ 0 ]][v[ 1 ]] = 1 ; // travelling to neibours for ( int [] u : adj.get(v[ 0 ]).get(v[ 1 ])) { // if not visited if (vis[u[ 0 ]][u[ 1 ]] == 0 ) { // call dfs function dfs(u, v, adj, vis); } // if visited else if (!(prev[ 0 ] == u[ 0 ] && prev[ 1 ] == u[ 1 ])) { // mark flag 1 flag = 1 ; // return dfs return ; } } } // Function to count cycles formed by // sticks static int countCycles( int N, int [][] A, int M) { // initializing adjaceny list List<List<List< int []> > > adj = new ArrayList<>(); for ( int i = 0 ; i <= N; i++) { List<List< int []> > innerAdj = new ArrayList<>(); for ( int j = 0 ; j < 2 ; j++) { innerAdj.add( new ArrayList<>()); } adj.add(innerAdj); } // Left and Right of same sticks are // connected with each other for ( int i = 1 ; i <= N; i++) { int [] left = { i, 0 }; int [] right = { i, 1 }; adj.get(i).get( 0 ).add(right); adj.get(i).get( 1 ).add(left); } // performing all M operations for ( int i = 0 ; i < M; i++) { int [] left = { A[i][ 0 ], A[i][ 1 ] }; int [] right = { A[i][ 2 ], A[i][ 3 ] }; adj.get(A[i][ 0 ]).get(A[i][ 1 ]).add(right); adj.get(A[i][ 2 ]).get(A[i][ 3 ]).add(left); } // answer initialized with zero int ans = 0 ; // visited array int [][] vis = new int [N + 1 ][ 2 ]; // calling all non visited nodes for ( int i = 1 ; i <= N; i++) { // if i is not visited if (vis[i][ 0 ] == 0 ) { // calling dfs function dfs( new int [] { i, 0 }, new int [] { - 1 , - 1 }, adj, vis); // adding flag to answer ans += flag; // resetting flag to zero flag = 0 ; } } // return total cycles return ans; } // Driver Code public static void main(String[] args) { // Input 1 int N = 5 ; int [][] A = { { 3 , 0 , 5 , 1 }, { 5 , 0 , 3 , 1 }, { 4 , 0 , 2 , 1 } }; int M = 3 ; // Function Call System.out.println(countCycles(N, A, M)); // Input 2 int N1 = 5 ; int [][] A1 = {}; int M1 = 0 ; // Function Call System.out.println(countCycles(N1, A1, M1)); } } // This code is contributed by Susobhan Akhuli |
Python3
# Python code to implement the approach # flag defined for detecting cycle flag = 0 # dfs function def dfs(v, prev, adj, vis): global flag # marking current state visited vis[v[ 0 ]][v[ 1 ]] = 1 # travelling to neibours for u in adj[v[ 0 ]][v[ 1 ]]: # if not visited if not vis[u[ 0 ]][u[ 1 ]]: # call dfs function dfs(u, v, adj, vis) # if visited elif prev ! = u: # mark flag 1 flag = 1 # return dfs return # Function to count cycles formed by sticks def countCycles(N, A, M): global flag # initializing adjaceny list adj = [[[] for i in range ( 2 )] for j in range (N + 1 )] # Left and Right of same sticks are connected with each other for i in range ( 1 , N + 1 ): adj[i][ 0 ].append((i, 1 )) adj[i][ 1 ].append((i, 0 )) # performing all M operations for i in range (M): adj[A[i][ 0 ]][A[i][ 1 ]].append((A[i][ 2 ], A[i][ 3 ])) adj[A[i][ 2 ]][A[i][ 3 ]].append((A[i][ 0 ], A[i][ 1 ])) # answer initialized with zero ans = 0 # visited array vis = [[ 0 for i in range ( 2 )] for j in range (N + 1 )] # calling all non visited nodes for i in range ( 1 , N + 1 ): # if i is not visited if not vis[i][ 0 ]: # calling dfs function dfs((i, 0 ), ( - 1 , - 1 ), adj, vis) # adding flag to answer ans + = flag # resetting flag to zero flag = 0 # return total cycles return ans # Driver Code if __name__ = = '__main__' : # Input 1 N = 5 A = [[ 3 , 0 , 5 , 1 ], [ 5 , 0 , 3 , 1 ], [ 4 , 0 , 2 , 1 ]] M = 3 # Function Call print (countCycles(N, A, M)) # Input 2 N1 = 5 A1 = [] M1 = 0 # Function Call print (countCycles(N1, A1, M1)) # This code is contributed by Susobhan Akhuli |
C#
// C# code to implement the approach using System; using System.Collections.Generic; class Solution { // flag defined for detecting cycle static int flag = 0; // dfs function static void dfs(Tuple< int , int > v, Tuple< int , int > prev, List<List<List<Tuple< int , int > > > > adj, List<List< int > > vis) { // marking current state visited vis[v.Item1][v.Item2] = 1; // travelling to neighbors foreach ( var u in adj[v.Item1][v.Item2]) { // if not visited if (vis[u.Item1][u.Item2] == 0) { // call dfs function dfs(u, v, adj, vis); } // if visited else if (!prev.Equals(u)) { // mark flag 1 flag = 1; // return dfs return ; } } } // Function to count cycles formed by sticks static int countCycles( int N, int [, ] A, int M) { // initializing adjacency list var adj = new List<List<List<Tuple< int , int > > > >( N + 1); for ( int i = 0; i <= N; i++) { adj.Add( new List<List<Tuple< int , int > > >() { new List<Tuple< int , int > >(), new List<Tuple< int , int > >() }); } // Left and Right of same sticks are // connected with each other for ( int i = 1; i <= N; i++) { adj[i][0].Add(Tuple.Create(i, 1)); adj[i][1].Add(Tuple.Create(i, 0)); } // performing all M operations for ( int i = 0; i < M; i++) { adj[A[i, 0]][A[i, 1]].Add( Tuple.Create(A[i, 2], A[i, 3])); adj[A[i, 2]][A[i, 3]].Add( Tuple.Create(A[i, 0], A[i, 1])); } // answer initialized with zero int ans = 0; // visited array var vis = new List<List< int > >(); for ( int i = 0; i <= N; i++) { vis.Add( new List< int >() { 0, 0 }); } // calling all non visited nodes for ( int i = 1; i <= N; i++) { // if i is not visited if (vis[i][0] == 0) { // calling dfs function dfs(Tuple.Create(i, 0), Tuple.Create(-1, -1), adj, vis); // adding flag to answer ans += flag; // resetting flag to zero flag = 0; } } // return total cycles return ans; } // Driver Code static void Main() { // Input 1 int N = 5; int [, ] A = { { 3, 0, 5, 1 }, { 5, 0, 3, 1 }, { 4, 0, 2, 1 } }; int M = 3; // Function Call Console.WriteLine(countCycles(N, A, M)); int N1 = 5; int [, ] A1 = {}; int M1 = 0; Console.WriteLine(countCycles(N1, A1, M1)); } } |
Javascript
// JavaScript code to implement the approach // flag defined for detecting cycle let flag = 0; // dfs function function dfs(v, prev, adj, vis) { // marking current state visited vis[v[0]][v[1]] = 1; // travelling to neighbours for (let u of adj[v[0]][v[1]]) { // if not visited if (!vis[u[0]][u[1]]) { // call dfs function dfs(u, v, adj, vis); } // if visited else if (prev[0] != u[0] || prev[1] != u[1]) { // mark flag 1 flag = 1; // return dfs return ; } } } // Function to count cycles formed by sticks function countCycles(N, A, M) { // initializing adjaceny list let adj = [... Array(N + 1)].map( () => [... Array(2)].map(() => [])); // Left and Right of same sticks are connected with each // other for (let i = 1; i <= N; i++) { adj[i][0].push([ i, 1 ]); adj[i][1].push([ i, 0 ]); } // performing all M operations for (let i = 0; i < M; i++) { adj[A[i][0]][A[i][1]].push([ A[i][2], A[i][3] ]); adj[A[i][2]][A[i][3]].push([ A[i][0], A[i][1] ]); } // answer initialized with zero let ans = 0; // visited array let vis = [... Array(N + 1)].map( () => [... Array(2)].map(() => 0)); // calling all non visited nodes for (let i = 1; i <= N; i++) { // if i is not visited if (!vis[i][0]) { // calling dfs function dfs([ i, 0 ], [ -1, -1 ], adj, vis); // adding flag to answer ans += flag; // resetting flag to zero flag = 0; } } // return total cycles return ans; } // Driver Code const N = 5; const A = [ [ 3, 0, 5, 1 ], [ 5, 0, 3, 1 ], [ 4, 0, 2, 1 ] ]; const M = 3; // Function Call console.log(countCycles(N, A, M)); const N1 = 5; const A1 = []; const M1 = 0; // Function Call console.log(countCycles(N1, A1, M1)); |
1 0
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
Please Login to comment...