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.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++ 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 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 |
# 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# 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 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: