# Product of minimum edge weight between all pairs of a Tree

Given a tree with N vertices and N-1 Edges. Let’s define a function F(a, b) which is equal to the minimum edge weight in the path between node a & b. The task is to calculate the product of all such F(a, b). Here a&b are unordered pairs and a!=b.

So, basically, we need to find the value of:

```                           where 0<=i<j<=n-1.
```

In the input, we will be given the value of N and then N-1 lines follow. Each line contains 3 integers u, v, w denoting edge between node u and v and it’s weight w. Since the product will be very large, output it modulo 10^9+7.
Examples:

```Input :
N = 4
1 2 1
1 3 3
4 3 2
Output : 12
Given tree is:
1
(1)/  \(3)
2     3
\(2)
4
We will calculate the minimum edge weight between all the pairs:
F(1, 2) = 1         F(2, 3) = 1
F(1, 3) = 3         F(2, 4) = 1
F(1, 4) = 2         F(3, 4) = 2
Product of all F(i, j) = 1*3*2*1*1*2 = 12 mod (10^9 +7) =12

Input :
N = 5
1 2 1
1 3 3
4 3 2
1 5 4
Output :
288
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

If we observe carefully then we will see that if there is a set of nodes in which minimum edge weight is w and if we add a node to this set that connects the node with the whole set by an edge of weight W such that W<w then path formed between recently added node to all nodes present in the set will have minimum weight W.
So, here we can apply Disjoint-Set Union concept to solve the problem.
First, sort the data structure according to decreasing weight. Initially assign all nodes as a single set. Now when we merge two sets then do the following:-

```      Product=(present weight)^(size of set1*size of set2).
```

We will multiply this product value for all edges of the tree.

Below is the implementation of the above approach:

 `// C++ Implementation of above approach ` `#include ` `using` `namespace` `std; ` `#define mod 1000000007 ` ` `  `// Function to return  (x^y) mod p ` `int` `power(``int` `x, unsigned ``int` `y, ``int` `p) ` `{ ` `    ``int` `res = 1; ` ` `  `    ``x = x % p; ` ` `  `    ``while` `(y > 0) { ` ` `  `        ``if` `(y & 1) ` `            ``res = (res * x) % p; ` `        ``y = y >> 1; ` `        ``x = (x * x) % p; ` `    ``} ` `    ``return` `res; ` `} ` ` `  `// Declaring size array globally ` `int` `size[300005]; ` `int` `freq[300004]; ` `vector > > edges; ` ` `  `// Initializing DSU data structure ` `void` `initialize(``int` `Arr[], ``int` `N) ` `{ ` `    ``for` `(``int` `i = 0; i < N; i++) { ` `        ``Arr[i] = i; ` `        ``size[i] = 1; ` `    ``} ` `} ` ` `  `// Function to find the root of ith ` `// node in the disjoint set ` `int` `root(``int` `Arr[], ``int` `i) ` `{ ` `    ``while` `(Arr[i] != i) { ` `        ``i = Arr[i]; ` `    ``} ` `    ``return` `i; ` `} ` ` `  `// Weighted union using Path Compression ` `void` `weighted_union(``int` `Arr[], ` `                    ``int` `size[], ``int` `A, ``int` `B) ` `{ ` `    ``int` `root_A = root(Arr, A); ` `    ``int` `root_B = root(Arr, B); ` ` `  `    ``// size of set A is small than size of set B ` `    ``if` `(size[root_A] < size[root_B]) { ` `        ``Arr[root_A] = Arr[root_B]; ` `        ``size[root_B] += size[root_A]; ` `    ``} ` ` `  `    ``// size of set B is small than size of set A ` `    ``else` `{ ` `        ``Arr[root_B] = Arr[root_A]; ` `        ``size[root_A] += size[root_B]; ` `    ``} ` `} ` ` `  `// Function to add an edge in the tree ` `void` `AddEdge(``int` `a, ``int` `b, ``int` `w) ` `{ ` `    ``edges.push_back({ w, { a, b } }); ` `} ` ` `  `// Bulid the tree ` `void` `MakeTree() ` `{ ` `    ``AddEdge(1, 2, 1); ` `    ``AddEdge(1, 3, 3); ` `    ``AddEdge(3, 4, 2); ` `} ` ` `  `// Function to return the required product ` `int` `MinProduct() ` `{ ` `    ``int` `result = 1; ` ` `  `    ``// Sorting the edges with respect to its weight ` `    ``sort(edges.begin(), edges.end()); ` ` `  `    ``// Start iterating in decreasing order of weight ` `    ``for` `(``int` `i = edges.size() - 1; i >= 0; i--) { ` ` `  `        ``// Determine Curret edge values ` `        ``int` `curr_weight = edges[i].first; ` `        ``int` `Node1 = edges[i].second.first; ` `        ``int` `Node2 = edges[i].second.second; ` ` `  `        ``// Calculate root of each node ` `        ``// and size of each set ` `        ``int` `Root1 = root(freq, Node1); ` `        ``int` `Set1_size = size[Root1]; ` `        ``int` `Root2 = root(freq, Node2); ` `        ``int` `Set2_size = size[Root2]; ` ` `  `        ``// Using the formula ` `        ``int` `prod = Set1_size * Set2_size; ` `        ``int` `Product = power(curr_weight, prod, mod); ` ` `  `        ``// Calculating final result ` `        ``result = ((result % mod) *  ` `                             ``(Product % mod)) % mod; ` ` `  `        ``// Weighted union using Path Compression ` `        ``weighted_union(freq, size, Node1, Node2); ` `    ``} ` `    ``return` `result % mod; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `n = 4; ` ` `  `    ``initialize(freq, n); ` ` `  `    ``MakeTree(); ` ` `  `    ``cout << MinProduct(); ` `} `

 `# Python3 implementation of the approach ` `mod ``=` `1000000007` ` `  `# Function to return (x^y) mod p ` `def` `power(x: ``int``, y: ``int``, p: ``int``) ``-``> ``int``: ` `    ``res ``=` `1` `    ``x ``%``=` `p ` `    ``while` `y > ``0``: ` `        ``if` `y & ``1``: ` `            ``res ``=` `(res ``*` `x) ``%` `p ` `        ``y ``=` `y ``/``/` `2` `        ``x ``=` `(x ``*` `x) ``%` `p ` `    ``return` `res ` ` `  `# Declaring size array globally ` `size ``=` `[``0``] ``*` `300005` `freq ``=` `[``0``] ``*` `300004` `edges ``=` `[] ` ` `  `# Initializing DSU data structure ` `def` `initialize(arr: ``list``, N: ``int``): ` `    ``for` `i ``in` `range``(N): ` `        ``arr[i] ``=` `i ` `        ``size[i] ``=` `1` ` `  `# Function to find the root of ith ` `# node in the disjoint set ` `def` `root(arr: ``list``, i: ``int``) ``-``> ``int``: ` `    ``while` `arr[i] !``=` `i: ` `        ``i ``=` `arr[i] ` `    ``return` `i ` ` `  `# Weighted union using Path Compression ` `def` `weighted_union(arr: ``list``, size: ``list``, A: ``int``, B: ``int``): ` `    ``root_A ``=` `root(arr, A) ` `    ``root_B ``=` `root(arr, B) ` ` `  `    ``# size of set A is small than size of set B ` `    ``if` `size[root_A] < size[root_B]: ` `        ``arr[root_A] ``=` `arr[root_B] ` `        ``size[root_B] ``+``=` `size[root_A] ` ` `  `    ``# size of set B is small than size of set A ` `    ``else``: ` `        ``arr[root_B] ``=` `arr[root_A] ` `        ``size[root_A] ``+``=` `size[root_B] ` ` `  `# Function to add an edge in the tree ` `def` `AddEdge(a: ``int``, b: ``int``, w: ``int``): ` `    ``edges.append((w, (a, b))) ` ` `  `# Bulid the tree ` `def` `makeTree(): ` `    ``AddEdge(``1``, ``2``, ``1``) ` `    ``AddEdge(``1``, ``3``, ``3``) ` `    ``AddEdge(``3``, ``4``, ``2``) ` ` `  `# Function to return the required product ` `def` `minProduct() ``-``> ``int``: ` `    ``result ``=` `1` ` `  `    ``# Sorting the edges with respect to its weight ` `    ``edges.sort(key ``=` `lambda` `a: a[``0``]) ` ` `  `    ``# Start iterating in decreasing order of weight ` `    ``for` `i ``in` `range``(``len``(edges) ``-` `1``, ``-``1``, ``-``1``): ` ` `  `        ``# Determine Curret edge values ` `        ``curr_weight ``=` `edges[i][``0``] ` `        ``node1 ``=` `edges[i][``1``][``0``] ` `        ``node2 ``=` `edges[i][``1``][``1``] ` ` `  `        ``# Calculate root of each node ` `        ``# and size of each set ` `        ``root1 ``=` `root(freq, node1) ` `        ``set1_size ``=` `size[root1] ` `        ``root2 ``=` `root(freq, node2) ` `        ``set2_size ``=` `size[root2] ` ` `  `        ``# Using the formula ` `        ``prod ``=` `set1_size ``*` `set2_size ` `        ``product ``=` `power(curr_weight, prod, mod) ` ` `  `        ``# Calculating final result ` `        ``result ``=` `((result ``%` `mod) ``*` `(product ``%` `mod)) ``%` `mod ` ` `  `        ``# Weighted union using Path Compression ` `        ``weighted_union(freq, size, node1, node2) ` ` `  `    ``return` `result ``%` `mod ` ` `  `# Driver Code ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``# Number of nodes and edges ` `    ``n ``=` `4` `    ``initialize(freq, n) ` `    ``makeTree() ` `    ``print``(minProduct()) ` ` `  `# This code is contributed by ` `# sanjeev2552 `

Output:
```12
```

Time Complexity : O(N*logN)

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.

Article Tags :