给定具有 N 个顶点和 N-1 个边的树。让我们定义一个函数F(a, b),它等于节点 a 和 b 之间路径中的最小边权重。任务是计算所有这些 F(a, b) 的乘积。这里 a&b 是无序对,a!=b。
所以,基本上,我们需要找到以下值:
其中 0<=i 在输入中,我们将获得 N 的值,然后是 N-1 行。每行包含 3 个整数 u、v、w,表示节点 u 和 v 之间的边及其权重 w。由于乘积将非常大,将其取模 10^9+7 输出。 如果我们仔细观察,那么我们将看到,如果有一组节点的最小边权重为 w,并且如果我们向该集合中添加一个节点,该节点通过权重为 W 的边将节点与整个集连接起来,使得 W< w 那么在最近添加的节点到集合中存在的所有节点之间形成的路径将具有最小权重 W。 我们将为树的所有边乘以这个乘积值。 时间复杂度: O(N*logN) 如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。
例子: 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
所以,在这里我们可以应用 Disjoint-Set Union 的概念来解决这个问题。
首先,按照权重递减对数据结构进行排序。最初将所有节点分配为一个集合。现在,当我们合并两组时,请执行以下操作:- Product=(present weight)^(size of set1*size of set2).
下面是上述方法的实现: C++
// C++ Implementation of above approach
#include
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
12