Given two trees each of N nodes. Removing an edge of the tree partitions the tree in two subsets.

Find the total maximum number of distinct edges (e1, e2): e1 from the first tree and e2 from the second tree such that it partitions both the trees into subsets with same nodes.

**Examples:**

Input: Same as the above figure N = 6

Tree 1 : {(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)}

Tree 2 :{(1, 2), (2, 3), (1, 6), (6, 5), (5, 4)}

Output :1

We can remove edge 3-4 in the first graph and edge 1-6 in the second graph.

The subsets will be {1, 2, 3} and {4, 5, 6}.

Input :N = 4

Tree 1 : {(1, 2), (1, 3), (1, 4)}

Tree 2 : {(1, 2), (2, 4), (1, 3)}

Output :2

We can select an edge 1-3 in the first graph and 1-3 in the second graph.

The subsets will be {3} and {1, 2, 4} for both graphs.

Also we can select an edge 1-4 in the first graph and 2-4 in the second graph.

The subsets will be {4} and {1, 2, 3} for both the graphs

** Approach : **

- The idea is to use hashing on trees, We will root both of trees at node 1, then We will assign random values to each node of the tree.
- We will do a dfs on the tree and, Suppose we are at node x, then we will keep a variable

subtree[x] that will store the hash value of all the nodes in its subtree. - One we did the above two steps, we are just left with storing the value of each subtree of nodes for both the trees the we get.
- We can use unordered map for it. The last step is to find how many common values of subtree[x] are there is both trees.
- Increase the count of distinct edges by +1 for every common values of subtree[x] for both trees.

Below is the implementation of above approach:

`// C++ implementation of the approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `const` `long` `long` `p = 97, MAX = 300005; ` ` ` `// This function checks whether ` `// a node is leaf node or not. ` `bool` `leaf1(` `long` `long` `NODE, ` `long` `long` `int` `deg1[]) ` `{ ` ` ` `if` `(deg1[NODE] == 1 and NODE != 1) ` ` ` `return` `true` `; ` ` ` `return` `false` `; ` `} ` ` ` `// This function calculates the Hash sum ` `// of all the children of a ` `// particular node for subtree 1 ` `void` `dfs3(` `long` `long` `curr, ` `long` `long` `par, ` ` ` `vector<` `long` `long` `int` `> tree1[], ` ` ` `long` `long` `int` `subtree1[], ` `long` `long` `int` `deg1[], ` ` ` `long` `long` `int` `node[]) ` `{ ` ` ` `for` `(` `auto` `& child : tree1[curr]) { ` ` ` `if` `(child == par) ` ` ` `continue` `; ` ` ` `dfs3(child, curr, tree1, subtree1, deg1, node); ` ` ` `} ` ` ` ` ` `// If the node is leaf node then ` ` ` `// there is no child, so hash sum ` ` ` `// will be same as the ` ` ` `// hash value for the node. ` ` ` `if` `(leaf1(curr, deg1) == ` `true` `) { ` ` ` `subtree1[curr] = node[curr]; ` ` ` `return` `; ` ` ` `} ` ` ` `long` `long` `sum = 0; ` ` ` ` ` `// Else calculate hash sum of all the ` ` ` `// children of a particular node, this is done ` ` ` `// by iterating on all the children of a node. ` ` ` `for` `(` `auto` `& child : tree1[curr]) { ` ` ` `sum = sum + subtree1[child]; ` ` ` `} ` ` ` ` ` `// store the hash value for ` ` ` `// all the subtree of current node ` ` ` `subtree1[curr] = node[curr] + sum; ` ` ` `return` `; ` `} ` ` ` `// This function checks whether ` `// a node is leaf node or not. ` `bool` `leaf2(` `long` `long` `NODE, ` `long` `long` `int` `deg2[]) ` `{ ` ` ` `if` `(deg2[NODE] == 1 and NODE != 1) ` ` ` `return` `true` `; ` ` ` `return` `false` `; ` `} ` ` ` `// This function calculates the Hash ` `// sum of all the children of ` `// a particular node for subtree 2. ` `void` `dfs4(` `long` `long` `curr, ` `long` `long` `par, ` ` ` `vector<` `long` `long` `int` `> tree2[], ` ` ` `long` `long` `int` `subtree2[], ` `long` `long` `int` `deg2[], ` ` ` `long` `long` `int` `node[]) ` `{ ` ` ` `for` `(` `auto` `& child : tree2[curr]) { ` ` ` `if` `(child == par) ` ` ` `continue` `; ` ` ` `dfs4(child, curr, tree2, subtree2, deg2, node); ` ` ` `} ` ` ` ` ` `// If the node is leaf node then ` ` ` `// there is no child, so hash sum will be ` ` ` `// same as the hash value for the node. ` ` ` `if` `(leaf2(curr, deg2) == ` `true` `) { ` ` ` `subtree2[curr] = node[curr]; ` ` ` `return` `; ` ` ` `} ` ` ` `long` `long` `sum = 0; ` ` ` ` ` `// Else calculate hash sum of all ` ` ` `// the children of a particular node, this is ` ` ` `// done by iterating on all the children of a node. ` ` ` `for` `(` `auto` `& child : tree2[curr]) { ` ` ` `sum = sum + subtree2[child]; ` ` ` `} ` ` ` ` ` `// store the hash value for ` ` ` `// all the subtree of current node ` ` ` `subtree2[curr] = node[curr] + sum; ` `} ` ` ` `// Calculates x^y in logN time. ` `long` `long` `exp` `(` `long` `long` `x, ` `long` `long` `y) ` `{ ` ` ` `if` `(y == 0) ` ` ` `return` `1; ` ` ` `else` `if` `(y & 1) ` ` ` `return` `x * ` `exp` `(x, y / 2) * ` `exp` `(x, y / 2); ` ` ` `else` ` ` `return` `exp` `(x, y / 2) * ` `exp` `(x, y / 2); ` `} ` ` ` `// This function helps in building the tree ` `void` `Insertt(vector<` `long` `long` `int` `> tree1[], ` ` ` `vector<` `long` `long` `int` `> tree2[], ` ` ` `long` `long` `int` `deg1[], ` `long` `long` `int` `deg2[]) ` `{ ` ` ` `// Building Tree 1 ` ` ` `tree1[1].push_back(2); ` ` ` `tree1[2].push_back(1); ` ` ` `tree1[2].push_back(3); ` ` ` `tree1[3].push_back(2); ` ` ` `tree1[3].push_back(4); ` ` ` `tree1[4].push_back(3); ` ` ` `tree1[4].push_back(5); ` ` ` `tree1[5].push_back(4); ` ` ` `tree1[5].push_back(6); ` ` ` `tree1[6].push_back(5); ` ` ` ` ` `// Since 6 is a leaf node for tree 1 ` ` ` `deg1[6] = 1; ` ` ` ` ` `// Building Tree 2 ` ` ` `tree2[1].push_back(2); ` ` ` `tree2[2].push_back(1); ` ` ` `tree2[2].push_back(3); ` ` ` `tree2[3].push_back(2); ` ` ` `tree2[1].push_back(6); ` ` ` `tree2[6].push_back(1); ` ` ` `tree2[6].push_back(5); ` ` ` `tree2[5].push_back(6); ` ` ` `tree2[5].push_back(4); ` ` ` `tree2[4].push_back(5); ` ` ` ` ` `// since both 3 and 4 are leaf nodes of tree 2 . ` ` ` `deg2[3] = 1; ` ` ` `deg2[4] = 1; ` `} ` ` ` `// Function to make the hash values ` `void` `TakeHash(` `long` `long` `n, ` `long` `long` `int` `node[]) ` `{ ` ` ` `// Take a very high prime ` ` ` `long` `long` `p = 97 * 13 * 19; ` ` ` ` ` `// Initialize random values to each node . ` ` ` `for` `(` `long` `long` `i = 1; i <= n; ++i) { ` ` ` ` ` `// A good random function is ` ` ` `// choosen for each node . ` ` ` `long` `long` `val = (` `rand` `() * ` `rand` `() * ` `rand` `()) ` ` ` `+ ` `rand` `() * ` `rand` `() + ` `rand` `(); ` ` ` `node[i] = val * p * ` `rand` `() + p * 13 * 19 * ` `rand` `() * ` `rand` `() * 101 * p; ` ` ` `p *= p; ` ` ` `p *= p; ` ` ` `} ` `} ` ` ` `// Function that returns the required answer ` `void` `solve(` `long` `long` `n, vector<` `long` `long` `int` `> tree1[], ` ` ` `vector<` `long` `long` `int` `> tree2[], ` `long` `long` `int` `subtree1[], ` ` ` `long` `long` `int` `subtree2[], ` `long` `long` `int` `deg1[], ` ` ` `long` `long` `int` `deg2[], ` `long` `long` `int` `node[]) ` `{ ` ` ` `// Do dfs on both trees to ` ` ` `// get subtree[x] for each node. ` ` ` `dfs3(1, 0, tree1, subtree1, deg1, node); ` ` ` `dfs4(1, 0, tree2, subtree2, deg2, node); ` ` ` ` ` `// cnt_tree1 and cnt_tree2 is used ` ` ` `// to store the count of all ` ` ` `// the hashes of every node . ` ` ` `unordered_map<` `long` `long` `, ` `long` `long` `> ` ` ` `cnt_tree1, cnt_tree2; ` ` ` `vector<` `long` `long` `> values; ` ` ` `for` `(` `long` `long` `i = 1; i <= n; ++i) { ` ` ` `long` `long` `value1 = subtree1[i]; ` ` ` `long` `long` `value2 = subtree2[i]; ` ` ` ` ` `// Store the subtree value of tree 1 ` ` ` `// in a vector to compare it later ` ` ` `// with subtree value of tree 2. ` ` ` `values.push_back(value1); ` ` ` ` ` `// increment the count of hash ` ` ` `// value for a subtree of a node. ` ` ` `cnt_tree1[value1]++; ` ` ` `cnt_tree2[value2]++; ` ` ` `} ` ` ` ` ` `// Stores the sum of all the hash values ` ` ` `// of children for root node of subtree 1. ` ` ` `long` `long` `root_tree1 = subtree1[1]; ` ` ` `long` `long` `root_tree2 = subtree2[1]; ` ` ` ` ` `// Stores the sum of all the hash values ` ` ` `// of children for root node of subtree 1. ` ` ` `cnt_tree1[root_tree1] = 0; ` ` ` `cnt_tree2[root_tree2] = 0; ` ` ` `long` `long` `answer = 0; ` ` ` `for` `(` `auto` `& x : values) { ` ` ` ` ` `// Check if for a given hash value for ` ` ` `// tree 1 is there any hash value which ` ` ` `// matches to hash value of tree 2 ` ` ` `// If yes, then its possible to divide ` ` ` `// the tree for this hash value ` ` ` `// into two equal subsets. ` ` ` `if` `(cnt_tree1[x] != 0 and cnt_tree2[x] != 0) ` ` ` `++answer; ` ` ` `} ` ` ` `cout << answer << endl; ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `vector<` `long` `long` `int` `> tree1[MAX], tree2[MAX]; ` ` ` `long` `long` `int` `node[MAX], deg1[MAX], deg2[MAX]; ` ` ` `long` `long` `int` `subtree1[MAX], subtree2[MAX]; ` ` ` `long` `long` `n = 6; ` ` ` ` ` `// To generate a good random function ` ` ` `srand` `(` `time` `(NULL)); ` ` ` `Insertt(tree1, tree2, deg1, deg2); ` ` ` `TakeHash(n, node); ` ` ` `solve(n, tree1, tree2, subtree1, subtree2, deg1, deg2, node); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

1

** Time Complexity **: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Find number of edges that can be broken in a tree such that Bitwise OR of resulting two trees are equal
- Split array into two equal length subsets such that all repetitions of a number lies in a single subset
- Minimum number of subsets with distinct elements
- Remove minimum number of elements such that no common element exist in both array
- Count of Nodes whose both immediate children are its prime factors
- Minimum number of groups of nodes such that no ancestor is present in the same group
- Rearrange string such that no pair of adjacent characters are of the same type
- Assign weights to edges such that longest path in terms of weights is minimized
- Color tree with minimum colors such that colors of edges incident to a vertex are different
- Minimum number of Nodes to be removed such that no subtree has more than K nodes
- Equally divide into two sets such that one set has maximum distinct elements
- Split array into maximum subarrays such that every distinct element lies in a single subarray
- Count subsets having distinct even numbers
- Partition the string in two parts such that both parts have at least k different characters
- Check if an array can be split into subsets of K consecutive elements
- Generic Trees(N-array Trees)
- Replace minimal number of characters to make all characters pair wise distinct
- Number of edges in mirror image of Complete binary tree
- Number of edges in a perfect binary tree with N levels
- Minimum number of edges required to be removed from an Undirected Graph to make it acyclic

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.