# Number of distinct pair of edges such that it partitions both trees into same subsets of nodes

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.

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. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.

**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;` `}` |

**Output:**

1

**Time Complexity **: O(N)