Thursday, October 9, 2025
HomeData Modelling & AICount ways to change direction of edges such that graph becomes acyclic

Count ways to change direction of edges such that graph becomes acyclic

Given a directed and unweighted graph consisting of N vertices and an array arr[] where ith vertex has a directed edge to arr[i]. The task is to find the number of ways to change the direction of edges such that the given graph is acyclic.

Examples: 

Input: N = 3, arr[] = {2, 3, 1} 
The directed graph form by the given information is: 
 

Directed Graph

Output:
Explanation: 
There are 6 possible ways to change the direction of edges to make graph acyclic: 
 

Way1

 

Way2

 

Way3

 

Way4

 

Way5

 

Way6

Approach: The idea is to check whether the Connected Components form a cycle or not. 

  • If the component is a path, then however we orient the edges we won’t form a cycle.
  • If the component has a cycle with N edges, then there are 2N ways to arrange all the edges out of which only 2 ways are going to form a cycle. So there are (2N – 2) ways to change the edges so that graph becomes acyclic.

Steps

  • Using Depth First Search(DFS) traversal find the cycles in the given graph and number of vertices associated with each cycle.
  • After DFS traversal, the total number of ways to change the direction of edges is the product of the following: 
    • Number of ways form by each cycle of X vertices is given by (2X – 2).
    • Number of ways form by each path of Y vertices is given by (2Y).

Below is the implementation of the above approach:  

C++




// C++ program to count the
// number of ways to change
// the direction of edges
// such that no cycle is
// present in the graph
#include <bits/stdc++.h>
using namespace std;
  
// Vector cycles[] to store
// the cycle with vertices
// associated with each cycle
vector<int> cycles;
  
// Count of cycle
int cyclecnt;
  
// Function to count the
// number of vertices in the
// current cycle
void DFSUtil(int u, int arr[], int vis[])
{
    cycles[cyclecnt]++;
    vis[u] = 3;
  
    // Returns when the same
    // initial vertex is found
    if (vis[arr[u]] == 3) {
        return;
    }
  
    // Recur for next vertex
    DFSUtil(arr[u], arr, vis);
}
  
// DFS traversal to detect
// the cycle in graph
void DFS(int u, int arr[], int vis[])
{
    // Marke vis[u] to 2 to
    // check for any cycle form
    vis[u] = 2;
  
    // If the vertex arr[u]
    // is not visited
    if (vis[arr[u]] == 0) {
        // Call DFS
        DFS(arr[u], arr, vis);
    }
  
    // If current node is
    // processed
    else if (vis[arr[u]] == 1) {
        vis[u] = 1;
        return;
    }
  
    // Cycle found, call DFSUtil
    // to count the number of
    // vertices in the current
    // cycle
    else {
        cycles.push_back(0);
  
        // Count number of
        // vertices in cycle
        DFSUtil(u, arr, vis);
        cyclecnt++;
    }
  
    // Current Node is processed
    vis[u] = 1;
}
  
// Function to count the
// number of ways
int countWays(int arr[], int N)
{
  
    int i, ans = 1;
  
    // To precompute the power
    // of 2
    int dp[N + 1];
    dp[0] = 1;
  
    // Storing power of 2
    for (int i = 1; i <= N; i++) {
        dp[i] = (dp[i - 1] * 2);
    }
  
    // Array vis[] created for
    // DFS traversal
    int vis[N + 1] = { 0 };
  
    // DFS traversal from Node 1
    for (int i = 1; i <= N; i++) {
        if (vis[i] == 0) {
  
            // Calling DFS
            DFS(i, arr, vis);
        }
    }
  
    int cnt = N;
  
    // Traverse the cycles array
    for (i = 0; i < cycles.size(); i++) {
  
        // Remove the vertices
        // which are part of a
        // cycle
        cnt -= cycles[i];
  
        // Count form by number
        // vertices form cycle
        ans *= dp[cycles[i]] - 2;
    }
  
    // Count form by number of
    // vertices not forming
    // cycle
    ans = (ans * dp[cnt]);
  
    return ans;
}
  
// Driver's Code
int main()
{
    int N = 3;
    int arr[] = { 0, 2, 3, 1 };
  
    // Function to count ways
    cout << countWays(arr, N);
    return 0;
}


Java




// Java program to count the number
// of ways to change the direction
// of edges such that no cycle is 
// present in the graph
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GFG{
      
// Vector cycles[] to store 
// the cycle with vertices 
// associated with each cycle 
static ArrayList<Integer> cycles; 
    
// Count of cycle 
static int cyclecnt; 
    
// Function to count the 
// number of vertices in the 
// current cycle 
static void DFSUtil(int u, int arr[], 
                           int vis[]) 
    cycles.set(cyclecnt, 
    cycles.get(cyclecnt) + 1); 
    vis[u] = 3
    
    // Returns when the same 
    // initial vertex is found 
    if (vis[arr[u]] == 3
    
        return
    
    
    // Recur for next vertex 
    DFSUtil(arr[u], arr, vis); 
    
// DFS traversal to detect 
// the cycle in graph 
static void DFS(int u, int arr[], int vis[]) 
      
    // Marke vis[u] to 2 to 
    // check for any cycle form 
    vis[u] = 2
    
    // If the vertex arr[u] 
    // is not visited 
    if (vis[arr[u]] == 0)
    {
          
        // Call DFS 
        DFS(arr[u], arr, vis); 
    
    
    // If current node is 
    // processed 
    else if (vis[arr[u]] == 1
    
        vis[u] = 1
        return
    
    
    // Cycle found, call DFSUtil 
    // to count the number of 
    // vertices in the current 
    // cycle 
    else
    
        cycles.add(0); 
    
        // Count number of 
        // vertices in cycle 
        DFSUtil(u, arr, vis); 
        cyclecnt++; 
    
    
    // Current Node is processed 
    vis[u] = 1
    
// Function to count the 
// number of ways 
static int countWays(int arr[], int N) 
    int i, ans = 1
    
    // To precompute the power 
    // of 2 
    int[] dp = new int[N + 1]; 
    dp[0] = 1
    
    // Storing power of 2 
    for(i = 1; i <= N; i++) 
    {
        dp[i] = (dp[i - 1] * 2); 
    
    
    // Array vis[] created for 
    // DFS traversal 
    int[] vis = new int[N + 1]; 
    
    // DFS traversal from Node 1 
    for(i = 1; i <= N; i++)
    
        if (vis[i] == 0)
        
              
            // Calling DFS 
            DFS(i, arr, vis); 
        
    
    
    int cnt = N; 
    
    // Traverse the cycles array 
    for(i = 0; i < cycles.size(); i++)
    
    
        // Remove the vertices 
        // which are part of a 
        // cycle 
        cnt -= cycles.get(i); 
    
        // Count form by number 
        // vertices form cycle 
        ans *= dp[cycles.get(i)] - 2
    
    
    // Count form by number of 
    // vertices not forming 
    // cycle 
    ans = (ans * dp[cnt]); 
    
    return ans; 
    
// Driver code
public static void main(String[] args)
{
    int N = 3
    int arr[] = { 0, 2, 3, 1 }; 
      
    cycles = new ArrayList<>();
      
    // Function to count ways 
    System.out.println(countWays(arr, N)); 
}
}
  
// This code is contributed by offbeat


Python3




# Python3 program to count the
# number of ways to change
# the direction of edges
# such that no cycle is
# present in the graph
  
# List cycles[] to store
# the cycle with vertices
# associated with each cycle
cycles = []
  
# Function to count the
# number of vertices in the
# current cycle
def DFSUtil(u, arr, vis, cyclecnt):
  
    cycles[cyclecnt] += 1
    vis[u] = 3
  
    # Returns when the same
    # initial vertex is found
    if (vis[arr[u]] == 3) :
        return
  
    # Recur for next vertex
    DFSUtil(arr[u], arr, vis, cyclecnt)
  
# DFS traversal to detect
# the cycle in graph
def DFS( u, arr, vis, cyclecnt):
  
    # Marke vis[u] to 2 to
    # check for any cycle form
    vis[u] = 2
  
    # If the vertex arr[u]
    # is not visited
    if (vis[arr[u]] == 0) :
          
        # Call DFS
        DFS(arr[u], arr, vis, cyclecnt)
  
    # If current node is
    # processed
    elif (vis[arr[u]] == 1):
        vis[u] = 1
        return
  
    # Cycle found, call DFSUtil
    # to count the number of
    # vertices in the current
    # cycle
    else :
        cycles.append(0)
  
        # Count number of
        # vertices in cycle
        DFSUtil(u, arr, vis,cyclecnt)
        cyclecnt += 1
  
    # Current Node is processed
    vis[u] = 1
  
# Function to count the
# number of ways
def countWays(arr, N,cyclecnt):
  
    ans = 1
  
    # To precompute the power
    # of 2
    dp = [0]*(N + 1)
    dp[0] = 1
  
    # Storing power of 2
    for i in range(1, N + 1):
        dp[i] = (dp[i - 1] * 2)
  
    # Array vis[] created for
    # DFS traversal
    vis = [0]*(N + 1)
  
    # DFS traversal from Node 1
    for i in range(1, N + 1) :
        if (vis[i] == 0) :
  
            # Calling DFS
            DFS(i, arr, vis, cyclecnt)
  
    cnt = N
  
    # Traverse the cycles array
    for i in range(len(cycles)) :
  
        # Remove the vertices
        # which are part of a
        # cycle
        cnt -= cycles[i]
  
        # Count form by number
        # vertices form cycle
        ans *= dp[cycles[i]] - 2
  
    # Count form by number of
    # vertices not forming
    # cycle
    ans = (ans * dp[cnt])
  
    return ans
  
# Driver's Code
if __name__ == "__main__":
      
    N = 3
    cyclecnt = 0
    arr = [ 0, 2, 3, 1 ]
  
    # Function to count ways
    print(countWays(arr, N,cyclecnt))
      
# This code is contributed by chitranayal


C#




// C# program to count the number
// of ways to change the direction
// of edges such that no cycle is 
// present in the graph
using System;
using System.Collections;
using System.Collections.Generic;
   
class GFG{
       
// Vector cycles[] to store 
// the cycle with vertices 
// associated with each cycle 
static ArrayList cycles; 
     
// Count of cycle 
static int cyclecnt; 
     
// Function to count the 
// number of vertices in the 
// current cycle 
static void DFSUtil(int u, int []arr, 
                           int []vis) 
    cycles[cyclecnt] = (int)cycles[cyclecnt] + 1;
    vis[u] = 3; 
      
    // Returns when the same 
    // initial vertex is found 
    if (vis[arr[u]] == 3) 
    
        return
    
      
    // Recur for next vertex 
    DFSUtil(arr[u], arr, vis); 
     
// DFS traversal to detect 
// the cycle in graph 
static void DFS(int u, int []arr, int []vis) 
      
    // Marke vis[u] to 2 to 
    // check for any cycle form 
    vis[u] = 2; 
     
    // If the vertex arr[u] 
    // is not visited 
    if (vis[arr[u]] == 0)
    {
          
        // Call DFS 
        DFS(arr[u], arr, vis); 
    
     
    // If current node is 
    // processed 
    else if (vis[arr[u]] == 1) 
    
        vis[u] = 1; 
        return
    
     
    // Cycle found, call DFSUtil 
    // to count the number of 
    // vertices in the current 
    // cycle 
    else
    
        cycles.Add(0); 
          
        // Count number of 
        // vertices in cycle 
        DFSUtil(u, arr, vis); 
        cyclecnt++; 
    
      
    // Current Node is processed 
    vis[u] = 1; 
     
// Function to count the 
// number of ways 
static int countWays(int []arr, int N) 
    int i, ans = 1; 
      
    // To precompute the power 
    // of 2 
    int[] dp = new int[N + 1]; 
    dp[0] = 1; 
     
    // Storing power of 2 
    for(i = 1; i <= N; i++) 
    {
        dp[i] = (dp[i - 1] * 2); 
    
     
    // Array vis[] created for 
    // DFS traversal 
    int[] vis = new int[N + 1]; 
     
    // DFS traversal from Node 1 
    for(i = 1; i <= N; i++)
    
        if (vis[i] == 0)
        
              
            // Calling DFS 
            DFS(i, arr, vis); 
        
    
     
    int cnt = N; 
     
    // Traverse the cycles array 
    for(i = 0; i < cycles.Count; i++)
    
          
        // Remove the vertices 
        // which are part of a 
        // cycle 
        cnt -= (int)cycles[i]; 
          
        // Count form by number 
        // vertices form cycle 
        ans *= dp[(int)cycles[i]] - 2; 
    
      
    // Count form by number of 
    // vertices not forming 
    // cycle 
    ans = (ans * dp[cnt]); 
     
    return ans; 
     
// Driver code
public static void Main(string[] args)
{
    int N = 3; 
    int []arr = new int[]{ 0, 2, 3, 1 }; 
       
    cycles = new ArrayList();
       
    // Function to count ways 
    Console.Write(countWays(arr, N)); 
}
}
  
// This code is contributed by rutvik_56


Javascript




<script>
  
// JavaScript program to count the number
// of ways to change the direction
// of edges such that no cycle is
// present in the graph
  
  
// Vector cycles[] to store
// the cycle with vertices
// associated with each cycle
let cycles;
// Count of cycle
let cyclecnt=0;
  
// Function to count the
// number of vertices in the
// current cycle
function DFSUtil(u,arr,vis)
{
    cycles[cyclecnt]++;
    vis[u] = 3;
     
    // Returns when the same
    // initial vertex is found
    if (vis[arr[u]] == 3)
    {
        return;
    }
     
    // Recur for next vertex
    DFSUtil(arr[u], arr, vis);
}
  
// DFS traversal to detect
// the cycle in graph
function DFS(u,arr,vis)
{
    // Marke vis[u] to 2 to
    // check for any cycle form
    vis[u] = 2;
     
    // If the vertex arr[u]
    // is not visited
    if (vis[arr[u]] == 0)
    {
           
        // Call DFS
        DFS(arr[u], arr, vis);
    }
     
    // If current node is
    // processed
    else if (vis[arr[u]] == 1)
    {
        vis[u] = 1;
        return;
    }
     
    // Cycle found, call DFSUtil
    // to count the number of
    // vertices in the current
    // cycle
    else
    {
        cycles.push(0);
     
        // Count number of
        // vertices in cycle
        DFSUtil(u, arr, vis);
        cyclecnt++;
    }
     
    // Current Node is processed
    vis[u] = 1;
}
  
// Function to count the
// number of ways
function countWays(arr,N)
{
    let i, ans = 1;
     
    // To precompute the power
    // of 2
    let dp = new Array(N + 1);
    for(let i=0;i<dp.length;i++)
    {
        dp[i]=0;
    }
    dp[0] = 1;
     
    // Storing power of 2
    for(i = 1; i <= N; i++)
    {
        dp[i] = (dp[i - 1] * 2);
    }
     
    // Array vis[] created for
    // DFS traversal
    let vis = new Array(N + 1);
       for(let i=0;i<vis.length;i++)
    {
        vis[i]=0;
    }
    // DFS traversal from Node 1
    for(i = 1; i <= N; i++)
    {
        if (vis[i] == 0)
        {
               
            // Calling DFS
            DFS(i, arr, vis);
        }
    }
     
    let cnt = N;
     
    // Traverse the cycles array
    for(i = 0; i < cycles.length; i++)
    {
     
        // Remove the vertices
        // which are part of a
        // cycle
        cnt -= cycles[i];
     
        // Count form by number
        // vertices form cycle
        ans *= dp[cycles[i]] - 2;
    }
     
    // Count form by number of
    // vertices not forming
    // cycle
    ans = (ans * dp[cnt]);
     
    return ans;
}
  
// Driver code
let N = 3;
let arr=[0, 2, 3, 1];
cycles =[];
// Function to count ways
document.write(countWays(arr, N));
  
// This code is contributed by avanitrachhadiya2155
  
</script>


Output: 

6

 

Time Complexity : O(V + E)
Auxiliary Space: O(n)

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Dominic
32348 POSTS0 COMMENTS
Milvus
87 POSTS0 COMMENTS
Nango Kala
6715 POSTS0 COMMENTS
Nicole Veronica
11878 POSTS0 COMMENTS
Nokonwaba Nkukhwana
11941 POSTS0 COMMENTS
Shaida Kate Naidoo
6837 POSTS0 COMMENTS
Ted Musemwa
7095 POSTS0 COMMENTS
Thapelo Manthata
6791 POSTS0 COMMENTS
Umr Jansen
6791 POSTS0 COMMENTS