Convert Directed Graph into a Tree
Last Updated :
23 Jun, 2021
Given an array arr[] of size N. There is an edge from i to arr[i]. The task is to convert this directed graph into tree by changing some of the edges. If for some i, arr[i] = i then i represents the root of the tree. In case of multiple answers print any of them.
Examples:
Input: arr[] = {6, 6, 0, 1, 4, 3, 3, 4, 0}
Output: {6, 6, 0, 1, 4, 3, 4, 4, 0}
Input: arr[] = {1, 2, 0};
Output: {0, 2, 0}.
Approach: Consider the 2nd example image above which shows an example of a functional graph. It consists of two cycles 1, 6, 3 and 4. Our goal is to make the graph consisting of exactly one cycle of exactly one vertex looped to itself.
Operation of change is equivalent to removing some outgoing edge and adding a new one, going to somewhat else vertex. Let's firstly make our graph containing only one cycle. To do so, one can choose any of initially presented cycles and say that it will be the only one. Then one should consider every other cycle, remove any of its in-cycle edges and replace it with an edge going to any of the chosen cycle's vertices. Thus the cycle will be broken and its vertices (along with tree ones) will be connected to the only chosen cycle. One will need to do exactly cycleCount - 1 such operations. Note that the removing of any non-cycle edge does not make sense, because it does not break any cycle.
The next thing is to make the cycle length be equal to 1. That might be already satisfied, if one will choose a cycle of minimal length and this length equals 1. Thus, if the initial graph contains any cycle of length 1, we are done with cycleCount - 1 operations. Otherwise, the cycle contains more than one vertex. It can be fixed with exactly one operation - one just needs to break any of in-cycle edges, say from u to arr[u], and add an edge from u to u. The graph will remain consisting of one cycle, but consisting of one self-looped vertex. In that case, we are done with cycleCount operations.
To do all the operations above, one can use DSU structure, or just a series of DFS. Note that there is no need in realisation of edge removing and creating, one just needs to analyze initial graph.
Below is the implementation of the above approach:
C++
// CPP program to convert directed graph into tree
#include <bits/stdc++.h>
using namespace std;
// Function to find root of the vertex
int find(int x, int a[], int vis[], int root[])
{
if (vis[x])
return root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return root[x];
}
// Function to convert directed graph into tree
void Graph_to_tree(int a[], int n)
{
// Vis array to check if an index is visited or not
// root[] array is to store parent of each vertex
int vis[n] = { 0 }, root[n] = { 0 };
// Find parent of each parent
for (int i = 0; i < n; i++)
find(a[i], a, vis, root);
// par stores the root of the resulting tree
int par = -1;
for (int i = 0; i < n; i++)
if (i == a[i])
par = i;
// If no self loop exists
if (par == -1) {
for (int i = 0; i < n; i++) {
// Make vertex in a cycle as root of the tree
if (i == find(a[i], a, vis, root)) {
par = i;
a[i] = i;
break;
}
}
}
// Remove all cycles
for (int i = 0; i < n; i++) {
if (i == find(a[i], a, vis, root)) {
a[i] = par;
}
}
// Print the resulting array
for (int i = 0; i < n; i++)
cout << a[i] << " ";
}
// Driver code to test above functions
int main()
{
int a[] = { 6, 6, 0, 1, 4, 3, 3, 4, 0 };
int n = sizeof(a) / sizeof(a[0]);
// Function call
Graph_to_tree(a, n);
}
Java
// Java program to convert
// directed graph into tree
import java.util.*;
class GFG
{
// Function to find root of the vertex
static int find(int x, int a[],
int vis[], int root[])
{
if (vis[x] == 1)
return root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return root[x];
}
// Function to convert directed graph into tree
static void Graph_to_tree(int a[], int n)
{
// Vis array to check if an index is
// visited or not root[] array is to
// store parent of each vertex
int []vis = new int[n];
int []root = new int[n];
// Find parent of each parent
for (int i = 0; i < n; i++)
find(a[i], a, vis, root);
// par stores the root of the resulting tree
int par = -1;
for (int i = 0; i < n; i++)
if (i == a[i])
par = i;
// If no self loop exists
if (par == -1)
{
for (int i = 0; i < n; i++)
{
// Make vertex in a cycle as root of the tree
if (i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break;
}
}
}
// Remove all cycles
for (int i = 0; i < n; i++)
{
if (i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
// Print the resulting array
for (int i = 0; i < n; i++)
System.out.print(a[i] + " ");
}
// Driver Code
static public void main ( String []arr)
{
int a[] = { 6, 6, 0, 1, 4, 3, 3, 4, 0 };
int n = a.length;
// Function call
Graph_to_tree(a, n);
}
}
// This code is contributed by 29AjayKumar
Python3
# A Python3 program to convert
# directed graph into tree
# Function to find root of the vertex
def find(x, a, vis, root):
if vis[x]:
return root[x]
vis[x] = 1
root[x] = x
root[x] = find(a[x], a, vis, root)
return root[x]
# Function to convert directed graph into tree
def Graph_To_Tree(a, n):
# Vis array to check if an index is visited or not
# root[] array is to store parent of each vertex
vis = [0] * n
root = [0] * n
# Find parent of each parent
for i in range(n):
find(a[i], a, vis, root)
# par stores the root of the resulting tree
par = -1
for i in range(n):
if i == a[i]:
par = i
# If no self loop exists
if par == -1:
for i in range(n):
# Make vertex in a cycle as root of the tree
if i == find(a[i], a, vis, root):
par = i
a[i] = i
break
# Remove all cycles
for i in range(n):
if i == find(a[i], a, vis, root):
a[i] = par
# Print the resulting array
for i in range(n):
print(a[i], end = " ")
# Driver Code
if __name__ == "__main__":
a = [6, 6, 0, 1, 4, 3, 3, 4, 0]
n = len(a)
# Function call
Graph_To_Tree(a, n)
# This code is contributed by
# sanjeev2552
C#
// C# program to convert
// directed graph into tree
using System;
using System.Collections.Generic;
class GFG
{
// Function to find root of the vertex
static int find(int x, int []a,
int []vis, int []root)
{
if (vis[x] == 1)
return root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return root[x];
}
// Function to convert directed graph into tree
static void Graph_to_tree(int []a, int n)
{
// Vis array to check if an index is
// visited or not root[] array is to
// store parent of each vertex
int []vis = new int[n];
int []root = new int[n];
// Find parent of each parent
for (int i = 0; i < n; i++)
find(a[i], a, vis, root);
// par stores the root of the resulting tree
int par = -1;
for (int i = 0; i < n; i++)
if (i == a[i])
par = i;
// If no self loop exists
if (par == -1)
{
for (int i = 0; i < n; i++)
{
// Make vertex in a cycle as root of the tree
if (i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break;
}
}
}
// Remove all cycles
for (int i = 0; i < n; i++)
{
if (i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
// Print the resulting array
for (int i = 0; i < n; i++)
Console.Write(a[i] + " ");
}
// Driver Code
static public void Main ( String []arr)
{
int []a = { 6, 6, 0, 1, 4, 3, 3, 4, 0 };
int n = a.Length;
// Function call
Graph_to_tree(a, n);
}
}
// This code is contributed by Princi Singh
JavaScript
<script>
// Javascript program to convert
// directed graph into tree
// Function to find root of the vertex
function find(x, a, vis, root)
{
if (vis[x] == 1)
return root[x];
vis[x] = 1;
root[x] = x;
root[x] = find(a[x], a, vis, root);
return root[x];
}
// Function to convert directed graph into tree
function Graph_to_tree(a, n)
{
// Vis array to check if an index is
// visited or not root[] array is to
// store parent of each vertex
var vis = Array(n).fill(0);
var root = Array(n).fill(0);
// Find parent of each parent
for (var i = 0; i < n; i++)
find(a[i], a, vis, root);
// par stores the root of the resulting tree
var par = -1;
for (var i = 0; i < n; i++)
if (i == a[i])
par = i;
// If no self loop exists
if (par == -1)
{
for (var i = 0; i < n; i++)
{
// Make vertex in a cycle as root of the tree
if (i == find(a[i], a, vis, root))
{
par = i;
a[i] = i;
break;
}
}
}
// Remove all cycles
for (var i = 0; i < n; i++)
{
if (i == find(a[i], a, vis, root))
{
a[i] = par;
}
}
// Print the resulting array
for (var i = 0; i < n; i++)
document.write(a[i] + " ");
}
// Driver Code
var a = [6, 6, 0, 1, 4, 3, 3, 4, 0];
var n = a.length;
// Function call
Graph_to_tree(a, n);
// This code is contributed by rrrtnx.
</script>
Output: 6 6 0 1 4 3 4 4 0
Similar Reads
Connected Components in an Undirected Graph
Given an undirected graph, the task is to return all the connected components in any order. Examples:Input: Consider the following graphExample of an undirected graphOutput: [[0, 1, 2], [3, 4]]Explanation: There are 2 different connected components.They are {0, 1, 2} and {3, 4}.Table of ContentAppro
15+ min read
Difference Between Graph and Tree
Graphs and trees are two fundamental data structures used in computer science to represent relationships between objects. While they share some similarities, they also have distinct differences that make them suitable for different applications. Difference Between Graph and Tree What is Graph?A grap
2 min read
Extra Edge in a Directed Rooted Tree
Given a Directed rooted tree of N vertices and N-1 edges. But now your friend has added an extra edge in the tree. You have to find an edge that could have been added by your friend. If there are multiple such possible edge then Print any. Examples: Input: N=3 edges = [[1,2],[1,3],[2,3]]Output: [2,3
9 min read
Clone a Directed Acyclic Graph
A directed acyclic graph (DAG) is a graph which doesn't contain a cycle and has directed edges. We are given a DAG, we need to clone it, i.e., create another graph that has copy of its vertices and edges connecting them. Examples: Input : 0 - - - > 1 - - - -> 4 | / \ ^ | / \ | | / \ | | / \ |
12 min read
Check if a given graph is tree or not
Write a function that returns true if a given undirected graph is a tree and false otherwise. For example, the following graph is a tree. But the following graph is not a tree. Approach 1: An undirected graph is a tree if it has the following properties. There is no cycle. The graph is connected. Fo
15+ min read
Difference between Tree edge and Back edge in graph
Tree Edge: It is an edge that is present in the tree obtained after performing DFS on the graph. All the Green edges are tree edges as shown in the below image. Back Edge: It is an edge (u, v) such that v is an ancestor of node u but not part of the DFS Traversal of the tree. Edge from 5 to 4 is a b
1 min read
Convert a tree to forest of even nodes
Given a tree of n even nodes. The task is to find the maximum number of edges to be removed from the given tree to obtain a forest of trees having an even number of nodes. This problem is always solvable as the given graph has even nodes.Examples: Input: Output: 2Explanation: By removing 2 edges sho
8 min read
Print Adjacency List for a Directed Graph
An Adjacency List is used for representing graphs. Here, for every vertex in the graph, we have a list of all the other vertices which the particular vertex has an edge to. Problem: Given the adjacency list and number of vertices and edges of a graph, the task is to represent the adjacency list for
6 min read
Convert a given tree to its Sum Tree
Given a Binary Tree where each node has positive and negative values. Convert this to a tree where each node contains the sum of the left and right sub trees in the original tree. The values of leaf nodes are changed to 0. For example, the following tree 10 / \ -2 6 / \ / \ 8 -4 7 5 should be change
15+ min read
Tree, Back, Edge and Cross Edges in DFS of Graph
Given a directed graph, the task is to identify tree, forward, back and cross edges present in the graph.Note: There can be multiple answers.Example:Input: GraphOutput:Tree Edges: 1->2, 2->4, 4->6, 1->3, 3->5, 5->7, 5->8 Forward Edges: 1->8 Back Edges: 6->2 Cross Edges: 5-
9 min read