Open in App
Not now

# Clone a Directed Acyclic Graph

• Difficulty Level : Medium
• Last Updated : 09 Mar, 2023

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
|        /  \        ^
|       /    \       |
|      /      \      |
|     /        \     |
|    /          \    |
|   /            \   |
v  v              v  |
2 - - - - - - - - -> 3

Output : Printing the output of the cloned graph gives:
0-1
1-2
2-3
3-4
1-3
1-4
0-2```

To clone a DAG without storing the graph itself within a hash (or dictionary in Python). To clone, it we basically do a depth-first traversal of the nodes, taking original node’s value and initializing new neighboring nodes with the same value, recursively doing, till the original graph is fully traversed. Below is the recursive approach to cloning a DAG (in Python). We make use of dynamic lists in Python, append operation to this list happens in constant time, hence, fast and efficient initialization of the graph.

Approach:

• Initialize an empty hash map to keep track of the visited nodes and their clones.
• Perform a DFS traversal of the original graph.
• For each visited node, create a clone of the node and add it to the hash map.
• For each outgoing edge of the visited node, check if the destination node is already in the hash map. If it is, add the corresponding clone to the clone of the visited node. If it is not, perform a DFS on the destination node and repeat the previous steps.
• Once the DFS traversal is complete, return the clone of the starting node.

Implementation:

## C++14

 `// C++ program to clone a directed acyclic graph.` `#include ` `using` `namespace` `std;`   `// Class to create a new graph node` `class` `Node ` `{` `    ``public``:` `        ``int` `key;` `        ``vector adj;` `        `  `        ``// key is the value of the node` `        ``// adj will be holding a dynamic` `        ``// list of all Node type neighboring` `        ``// nodes` `        ``Node(``int` `key) ` `        ``{` `            ``this``->key = key; ` `        ``}` `};`   `// Function to print a graph,` `// depth-wise, recursively` `void` `printGraph(Node *startNode,` `                ``vector<``bool``> &visited) ` `{` `    `  `    ``// Visit only those nodes who have any` `    ``// neighboring nodes to be traversed` `    ``if` `(!startNode->adj.empty()) ` `    ``{` `        `  `        ``// Loop through the neighboring nodes` `        ``// of this node. If source node not already` `        ``// visited, print edge from source to` `        ``// neighboring nodes. After visiting all` `        ``// neighbors of source node, mark its visited` `        ``// flag to true` `        ``for``(``auto` `i : startNode->adj)` `        ``{` `            ``if` `(!visited[startNode->key]) ` `            ``{` `                ``cout << ``"edge "` `<< startNode ` `                     ``<< ``"-"` `<< i ` `                     ``<< ``":"` `<< startNode->key ` `                     ``<< ``"-"` `<< i->key ` `                     ``<< endl;` `                ``if` `(!visited[i->key])` `                ``{` `                    ``printGraph(i, visited);` `                    ``visited[i->key] = ``true``;` `                ``}` `            ``}` `        ``}` `    ``}` `}`   `// Function to clone a graph. To do this, we ` `// start reading the original graph depth-wise,` `// recursively. If we encounter an unvisited ` `// node in original graph, we initialize a ` `// new instance of Node for cloned graph with` `// key of original node` `Node *cloneGraph(Node *oldSource, ` `                 ``Node *newSource, ` `                 ``vector<``bool``> &visited)` `{` `    ``Node *clone = NULL;` `    `  `    ``if` `(!visited[oldSource->key] && ` `        ``!oldSource->adj.empty())` `    ``{` `        ``for``(``auto` `old : oldSource->adj) ` `        ``{` `            `  `            ``// Below check is for backtracking, so new` `            ``// nodes don't get initialized everytime` `            ``if` `(clone == NULL || ` `               ``(clone != NULL && ` `               ``clone->key != old->key))` `                ``clone = ``new` `Node(old->key);` `                `  `            ``newSource->adj.push_back(clone);` `            ``cloneGraph(old, clone, visited);` `            `  `            ``// Once, all neighbors for that particular node` `            ``// are created in cloned graph, code backtracks` `            ``// and exits from that node, mark the node as` `            ``// visited in original graph, and traverse the` `            ``// next unvisited` `            ``visited[old->key] = ``true``;` `        ``}` `    ``}` `    ``return` `newSource;` `}`   `// Driver Code` `int` `main() ` `{` `    ``Node *n0 = ``new` `Node(0);` `    ``Node *n1 = ``new` `Node(1);` `    ``Node *n2 = ``new` `Node(2);` `    ``Node *n3 = ``new` `Node(3);` `    ``Node *n4 = ``new` `Node(4);` `    `  `    ``n0->adj.push_back(n1);` `    ``n0->adj.push_back(n2);` `    ``n1->adj.push_back(n2);` `    ``n1->adj.push_back(n3);` `    ``n1->adj.push_back(n4);` `    ``n2->adj.push_back(n3);` `    ``n3->adj.push_back(n4);` `    `  `    ``// Flag to check if a node is already visited.` `    ``// Stops indefinite looping during recursion` `    ``vector<``bool``> visited(5, ``false``);` `    ``cout << ``"Graph Before Cloning:-\n"``;` `    ``printGraph(n0, visited);` `    ``visited = { ``false``, ``false``, ``false``, ``false``, ``false` `};` `    `  `    ``cout << ``"\nGraph Before Starts:-\n"``;` `    ``Node *clonedGraphHead = cloneGraph(` `        ``n0, ``new` `Node(n0->key), visited);` `    ``cout << ``"Cloning Process Completes.\n"``;` `    `  `    ``visited = { ``false``, ``false``, ``false``, ``false``, ``false` `};` `    ``cout << ``"\nGraph After Cloning:-\n"``;` `    ``printGraph(clonedGraphHead, visited);` `    `  `    ``return` `0;` `}`   `// This code is contributed by sanjeev2552`

## Java

 `// Java program to clone a directed acyclic graph.` `import` `java.util.*;`   `class` `GFG{`   `// Class to create a new graph node` `static` `class` `Node` `{` `    ``int` `key;` `    ``ArrayList adj = ``new` `ArrayList();` `    `  `    ``// key is the value of the node` `    ``// adj will be holding a dynamic` `    ``// list of all Node type neighboring` `    ``// nodes` `    ``Node(``int` `key)` `    ``{` `        ``this``.key = key;` `    ``}` `}`   `// Function to print a graph,` `// depth-wise, recursively` `static` `void` `printGraph(Node startNode,` `                       ``boolean``[] visited)` `{` `    `  `    ``// Visit only those nodes who have any` `    ``// neighboring nodes to be traversed` `    ``if` `(!startNode.adj.isEmpty())` `    ``{` `        `  `        ``// Loop through the neighboring nodes` `        ``// of this node. If source node not already` `        ``// visited, print edge from source to` `        ``// neighboring nodes. After visiting all` `        ``// neighbors of source node, mark its visited` `        ``// flag to true` `        ``for``(Node i : startNode.adj)` `        ``{` `            ``if` `(!visited[startNode.key])` `            ``{` `                ``System.out.println(``"edge "` `+ startNode +` `                             ``"-"` `+ i + ``":"` `+ startNode.key + ` `                             ``"-"` `+ i.key);` `                `  `                ``if` `(!visited[i.key])` `                ``{` `                    ``printGraph(i, visited);` `                    ``visited[i.key] = ``true``;` `                ``}` `            ``}` `        ``}` `    ``}` `}`   `// Function to clone a graph. To do this, we` `// start reading the original graph depth-wise,` `// recursively. If we encounter an unvisited` `// node in original graph, we initialize a` `// new instance of Node for cloned graph with` `// key of original node` `static` `Node cloneGraph(Node oldSource,` `                       ``Node newSource,` `                       ``boolean``[] visited)` `{` `    ``Node clone = ``null``;` `    `  `    ``if` `(!visited[oldSource.key] &&` `        ``!oldSource.adj.isEmpty())` `    ``{` `        ``for``(Node old : oldSource.adj)` `        ``{` `            `  `            ``// Below check is for backtracking, so new` `            ``// nodes don't get initialized everytime` `            ``if` `(clone == ``null` `||` `               ``(clone != ``null` `&&` `                ``clone.key != old.key))` `                ``clone = ``new` `Node(old.key);` `                `  `            ``newSource.adj.add(clone);` `            ``cloneGraph(old, clone, visited);` `            `  `            ``// Once, all neighbors for that particular node` `            ``// are created in cloned graph, code backtracks` `            ``// and exits from that node, mark the node as` `            ``// visited in original graph, and traverse the` `            ``// next unvisited` `            ``visited[old.key] = ``true``;` `        ``}` `    ``}` `    ``return` `newSource;` `}`   `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `    ``Node n0 = ``new` `Node(``0``);` `    ``Node n1 = ``new` `Node(``1``);` `    ``Node n2 = ``new` `Node(``2``);` `    ``Node n3 = ``new` `Node(``3``);` `    ``Node n4 = ``new` `Node(``4``);` `    `  `    ``n0.adj.add(n1);` `    ``n0.adj.add(n2);` `    ``n1.adj.add(n2);` `    ``n1.adj.add(n3);` `    ``n1.adj.add(n4);` `    ``n2.adj.add(n3);` `    ``n3.adj.add(n4);` `    `  `    ``// Flag to check if a node is already visited.` `    ``// Stops indefinite looping during recursion` `    ``boolean` `visited[] = ``new` `boolean``[``5``];` `    ``System.out.println(``"Graph Before Cloning:-"``);` `    ``printGraph(n0, visited);` `    ``Arrays.fill(visited, ``false``);` `    `  `    ``System.out.println(``"\nCloning Process Starts"``);` `    ``Node clonedGraphHead = cloneGraph(` `        ``n0, ``new` `Node(n0.key), visited);` `    ``System.out.println(``"Cloning Process Completes."``);` `    `  `    ``Arrays.fill(visited, ``false``);` `    ``System.out.println(``"\nGraph After Cloning:-"``);` `    ``printGraph(clonedGraphHead, visited);` `}` `}`   `// This code is contributed by adityapande88`

## Python3

 `# Python program to clone a directed acyclic graph.`   `# Class to create a new graph node` `class` `Node():`   `    ``# key is the value of the node` `    ``# adj will be holding a dynamic` `    ``# list of all Node type neighboring` `    ``# nodes` `    ``def` `__init__(``self``, key ``=` `None``, adj ``=` `None``):` `        ``self``.key ``=` `key` `        ``self``.adj ``=` `adj`   `# Function to print a graph, depth-wise, recursively` `def` `printGraph(startNode, visited):`   `    ``# Visit only those nodes who have any` `    ``# neighboring nodes to be traversed` `    ``if` `startNode.adj ``is` `not` `None``:`   `        ``# Loop through the neighboring nodes` `        ``# of this node. If source node not already` `        ``# visited, print edge from source to` `        ``# neighboring nodes. After visiting all` `        ``# neighbors of source node, mark its visited` `        ``# flag to true` `        ``for` `i ``in` `startNode.adj:` `            ``if` `visited[startNode.key] ``=``=` `False` `:` `                ``print``(``"edge %s-%s:%s-%s"``%``(``hex``(``id``(startNode)), ``hex``(``id``(i)), startNode.key, i.key))` `                ``if` `visited[i.key] ``=``=` `False``:` `                    ``printGraph(i, visited)` `                    ``visited[i.key] ``=` `True`   `# Function to clone a graph. To do this, we start` `# reading the original graph depth-wise, recursively` `# If we encounter an unvisited node in original graph,` `# we initialize a new instance of Node for` `# cloned graph with key of original node` `def` `cloneGraph(oldSource, newSource, visited):` `    ``clone ``=` `None` `    ``if` `visited[oldSource.key] ``is` `False` `and` `oldSource.adj ``is` `not` `None``:` `        ``for` `old ``in` `oldSource.adj:`   `            ``# Below check is for backtracking, so new` `            ``# nodes don't get initialized everytime` `            ``if` `clone ``is` `None` `or``(clone ``is` `not` `None` `and` `clone.key !``=` `old.key):` `                ``clone ``=` `Node(old.key, [])` `            ``newSource.adj.append(clone)` `            ``cloneGraph(old, clone, visited)`   `            ``# Once, all neighbors for that particular node` `            ``# are created in cloned graph, code backtracks` `            ``# and exits from that node, mark the node as` `            ``# visited in original graph, and traverse the` `            ``# next unvisited` `            ``visited[old.key] ``=` `True` `    ``return` `newSource`   `# Creating DAG to be cloned` `# In Python, we can do as many assignments of` `# variables in one single line by using commas` `n0, n1, n2 ``=` `Node(``0``, []), Node(``1``, []), Node(``2``, [])` `n3, n4 ``=` `Node(``3``, []), Node(``4``)` `n0.adj.append(n1)` `n0.adj.append(n2)` `n1.adj.append(n2)` `n1.adj.append(n3)` `n1.adj.append(n4)` `n2.adj.append(n3)` `n3.adj.append(n4)`   `# flag to check if a node is already visited.` `# Stops indefinite looping during recursion` `visited ``=` `[``False``]``*` `(``5``)` `print``(``"Graph Before Cloning:-"``)` `printGraph(n0, visited)`   `visited ``=` `[``False``]``*` `(``5``)` `print``(``"\nCloning Process Starts"``)` `clonedGraphHead ``=` `cloneGraph(n0, Node(n0.key, []), visited)` `print``(``"Cloning Process Completes."``)`   `visited ``=` `[``False``]``*``(``5``)` `print``(``"\nGraph After Cloning:-"``)` `printGraph(clonedGraphHead, visited)`

## Javascript

 `// Javascript program to clone a directed acyclic graph.`   `      ``// Class to create a new graph node` `      ``class Node {` `        ``constructor(key) {` `          ``// key is the value of the node` `          ``// adj will be holding a dynamic` `          ``// list of all Node type neighboring` `          ``// nodes` `          ``this``.key = key;` `          ``this``.adj = [];` `        ``}` `      ``}`   `      ``// Function to print a graph,` `      ``// depth-wise, recursively` `      ``function` `printGraph(startNode, visited) {` `        ``// Visit only those nodes who have any` `        ``// neighboring nodes to be traversed`   `        ``if` `(startNode.adj.length != 0) {` `          ``// Loop through the neighboring nodes` `          ``// of this node. If source node not already` `          ``// visited, print edge from source to` `          ``// neighboring nodes. After visiting all` `          ``// neighbors of source node, mark its visited` `          ``// flag to true` `          ``for` `(i ``in` `startNode.adj) {` `            ``if` `(!visited[startNode.key]) {` `              ``console.log(` `                ``"edge "` `+` `                  ``startNode +` `                  ``"-"` `+` `                  ``startNode.adj[i] +` `                  ``":"` `+` `                  ``startNode.key +` `                  ``"-"` `+` `                  ``startNode.adj[i].key` `              ``);`   `              ``if` `(!visited[i.key]) {` `                ``printGraph(startNode.adj[i], visited);` `                ``visited[i.key] = ``true``;` `              ``}` `            ``}` `          ``}` `        ``}` `      ``}`   `      ``// Function to clone a graph. To do this, we` `      ``// start reading the original graph depth-wise,` `      ``// recursively. If we encounter an unvisited` `      ``// node in original graph, we initialize a` `      ``// new instance of Node for cloned graph with` `      ``// key of original node` `      ``function` `cloneGraph(oldSource, newSource, visited) {` `        ``clone = ``null``;`   `        ``if` `(!visited[oldSource.key] && !(oldSource.adj.length == 0)) {` `          ``for` `(let old ``in` `oldSource.adj) {` `            ``// Below check is for backtracking, so new` `            ``// nodes don't get initialized everytime` `            ``if` `(` `              ``clone == ``null` `||` `              ``(clone != ``null` `&& clone.key != oldSource.adj[old].key)` `            ``)` `              ``clone = ``new` `Node(oldSource.adj[old].key);`   `            ``newSource.adj.push(clone);` `            ``cloneGraph(oldSource.adj[old], clone, visited);`   `            ``// Once, all neighbors for that particular node` `            ``// are created in cloned graph, code backtracks` `            ``// and exits from that node, mark the node as` `            ``// visited in original graph, and traverse the` `            ``// next unvisited` `            ``visited[oldSource.adj[old].key] = ``true``;` `          ``}` `        ``}` `        ``return` `newSource;` `      ``}`   `      ``// Driver Code`   `      ``n0 = ``new` `Node(0);` `      ``n1 = ``new` `Node(1);` `      ``n2 = ``new` `Node(2);` `      ``n3 = ``new` `Node(3);` `      ``n4 = ``new` `Node(4);`   `      ``n0.adj.push(n1);` `      ``n0.adj.push(n2);` `      ``n1.adj.push(n2);` `      ``n1.adj.push(n3);` `      ``n1.adj.push(n4);` `      ``n2.adj.push(n3);` `      ``n3.adj.push(n4);`   `      ``// Flag to check if a node is already visited.` `      ``// Stops indefinite looping during recursion`   `      ``visited = [``false``, ``false``, ``false``, ``false``, ``false``];` `      ``console.log(``"Graph Before Cloning:"``);` `      ``printGraph(n0, visited);` `      ``visited = [``false``, ``false``, ``false``, ``false``, ``false``];`   `      ``console.log(``"Graph Before Starts:"``);` `      ``clonedGraphHead = cloneGraph(n0, ``new` `Node(n0.key), visited);` `      ``console.log(``"Cloning Process Completes."``);`   `      ``visited = [``false``, ``false``, ``false``, ``false``, ``false``];` `      ``console.log(``"Graph After Cloning:"``);` `      ``printGraph(clonedGraphHead, visited);`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `GFG` `{` `    ``class` `Node` `    ``{` `        ``public` `int` `Key { ``get``; ``set``; }` `        ``public` `List Adj { ``get``; ``set``; }`   `        ``public` `Node(``int` `key)` `        ``{` `            ``Key = key;` `            ``Adj = ``new` `List();` `        ``}` `    ``}`   `    ``static` `void` `PrintGraph(Node startNode, ``bool``[] visited)` `    ``{` `        ``if` `(startNode.Adj.Count > 0)` `        ``{` `            ``foreach` `(``var` `i ``in` `startNode.Adj)` `            ``{` `                ``if` `(!visited[startNode.Key])` `                ``{` `                    ``Console.WriteLine(``"edge "` `+ startNode + ``"-"` `+ i + ``":"` `+ startNode.Key + ``"-"` `+ i.Key);`   `                    ``if` `(!visited[i.Key])` `                    ``{` `                        ``PrintGraph(i, visited);` `                        ``visited[i.Key] = ``true``;` `                    ``}` `                ``}` `            ``}` `        ``}` `    ``}`   `    ``static` `Node CloneGraph(Node oldSource, Node newSource, ``bool``[] visited)` `    ``{` `        ``Node clone = ``null``;`   `        ``if` `(!visited[oldSource.Key] && oldSource.Adj.Count > 0)` `        ``{` `            ``foreach` `(``var` `old ``in` `oldSource.Adj)` `            ``{` `                ``if` `(clone == ``null` `|| (clone != ``null` `&& clone.Key != old.Key))` `                    ``clone = ``new` `Node(old.Key);`   `                ``newSource.Adj.Add(clone);` `                ``CloneGraph(old, clone, visited);` `                ``visited[old.Key] = ``true``;` `            ``}` `        ``}`   `        ``return` `newSource;` `    ``}`   `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``var` `n0 = ``new` `Node(0);` `        ``var` `n1 = ``new` `Node(1);` `        ``var` `n2 = ``new` `Node(2);` `        ``var` `n3 = ``new` `Node(3);` `        ``var` `n4 = ``new` `Node(4);`   `        ``n0.Adj.Add(n1);` `        ``n0.Adj.Add(n2);` `        ``n1.Adj.Add(n2);` `        ``n1.Adj.Add(n3);` `        ``n1.Adj.Add(n4);` `        ``n2.Adj.Add(n3);` `        ``n3.Adj.Add(n4);`   `        ``bool``[] visited = ``new` `bool``[5];` `        ``Console.WriteLine(``"Graph Before Cloning:-"``);` `        ``PrintGraph(n0, visited);` `        ``Array.Fill(visited, ``false``);`   `        ``Console.WriteLine(``"\nCloning Process Starts"``);` `        ``var` `clonedGraphHead = CloneGraph(n0, ``new` `Node(n0.Key), visited);` `        ``Console.WriteLine(``"Cloning Process Completes."``);`   `        ``Array.Fill(visited, ``false``);` `        ``Console.WriteLine(``"\nGraph After Cloning:-"``);` `        ``PrintGraph(clonedGraphHead, visited);` `    ``}` `}` `// this code is contributed by writer`

Output

```Graph Before Cloning:-
edge 0x1017e70-0x1017ea0:0-1
edge 0x1017ea0-0x1017ed0:1-2
edge 0x1017ed0-0x1017f00:2-3
edge 0x1017f00-0x1017f30:3-4
edge 0x1017ea0-0x1017f00:1-3
edge 0x1017ea0-0x1017f30:1-4
edge 0x1017e70-0x1017ed0:0-2

Graph Before Starts:-
Cloning Process Completes.

Graph After Cloning:-
edge 0x1019020-0x1019050:0-1
edge 0x1019050-0x10190a0:1-2
edge 0x10190a0-0x10190f0:2-3
edge 0x10190f0-0x1019140:3-4
edge 0x1019050-0x1019190:1-3
edge 0x1019050-0x10191e0:1-4
edge 0x1019020-0x1019240:0-2```

Creating the DAG by appending adjacent edges to the vertex happens in O(1) time. Cloning of the graph takes O(E+V) time.

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

This article is contributed by Raveena. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Related Article: Clone an Undirected Graph

My Personal Notes arrow_drop_up
Related Articles