Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

Find the number of sticks that forms cycle

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

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));


Output

1
0

Time Complexity: O(N)  
Auxiliary Space: O(N)

Related Articles:


My Personal Notes arrow_drop_up
Last Updated : 29 Mar, 2023
Like Article
Save Article
Similar Reads
Related Tutorials