# 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 2Output :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) =12Input :N = 5 1 2 1 1 3 3 4 3 2 1 5 4Output :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++ Implementation of above approach ` `#include <bits/stdc++.h> ` `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<pair<` `int` `, pair<` `int` `, ` `int` `> > > 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(); ` `} ` |

*chevron_right*

*filter_none*

**Output:**

12

**Time Complexity : ** O(N*logN)

## Recommended Posts:

- Remove all outgoing edges except edge with minimum weight
- Count number of paths whose weight is exactly X and has at-least one edge of weight M
- Find the weight of the minimum spanning tree
- Shortest Path in a weighted Graph where weight of an edge is 1 or 2
- Minimum Product Spanning Tree
- Sum and Product of maximum and minimum element in Binary Tree
- Sum and Product of minimum and maximum element of Binary Search Tree
- Minimum edge reversals to make a root
- Number of Paths of Weight W in a K-ary tree
- Count the nodes in the given tree whose weight is even
- Maximum edge removal from tree to make even forest
- Tree, Back, Edge and Cross Edges in DFS of Graph
- Count the nodes in the given tree whose weight is even parity
- Count the nodes of the given tree whose weight has X as a factor
- Count the nodes in the given tree whose sum of digits of weight is odd

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.