 Open in App
Not now

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

• Difficulty Level : Expert
• Last Updated : 30 Jan, 2023

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: Output:
Explanation:
There are 6 possible ways to change the direction of edges to make graph acyclic:      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 ``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``;``    ``}` `    ``// Recurr 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 = 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 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``;``    ``}``  ` `    ``// Recurr 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` `    ``# Recurr 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``;``    ``}``    ` `    ``// Recurr 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 = 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

 ``

Output:

`6`

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

My Personal Notes arrow_drop_up