Open In App

Find the number of sticks that forms cycle

Last Updated : 29 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads