Related Articles

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

• Difficulty Level : Hard
• Last Updated : 24 Jun, 2021

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```

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++

 `// 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;``int` `freq;``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 } });``}` `// Build 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 Current 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

 `# 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)))` `# Build 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 Current 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.  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.

My Personal Notes arrow_drop_up