You are given an unrooted weighted tree with n vertices representing servers numbered from 0 to n - 1, an array edges where edges[i] = [ai, bi, weighti] represents a bidirectional edge between vertices ai and bi of weight weighti. You are also given an integer signalSpeed.
Two servers a and b are connectable through a server c if:
a < b, a != c and b != c.
The distance from c to a is divisible by signalSpeed.
The distance from c to b is divisible by signalSpeed.
The path from c to b and the path from c to a do not share any edges.
Return an integer arraycountof lengthnwherecount[i]is the number of server pairs that are connectable throughthe serveri.
Example 1:
Input: edges = [[0,1,1],[1,2,5],[2,3,13],[3,4,9],[4,5,2]], signalSpeed = 1
Output: [0,4,6,6,4,0]
Explanation: Since signalSpeed is 1, count[c] is equal to the number of pairs of paths that start at c and do not share any edges.
In the case of the given path graph, count[c] is equal to the number of servers to the left of c multiplied by the servers to the right of c.
Example 2:
Input: edges = [[0,6,3],[6,5,3],[0,3,1],[3,2,7],[3,1,6],[3,4,2]], signalSpeed = 3
Output: [2,0,0,0,0,0,2]
Explanation: Through server 0, there are 2 pairs of connectable servers: (4, 5) and (4, 6).
Through server 6, there are 2 pairs of connectable servers: (4, 5) and (0, 5).
It can be shown that no two servers are connectable through servers other than 0 and 6.
Constraints:
2 <= n <= 1000
edges.length == n - 1
edges[i].length == 3
0 <= ai, bi < n
edges[i] = [ai, bi, weighti]
1 <= weighti <= 106
1 <= signalSpeed <= 106
The input is generated such that edges represents a valid tree.
Solutions
Solution 1: Enumeration + DFS
Thinking
A pair is counted at a hub when the two paths are edge-disjoint and both distances are divisible by \(\textit{signalSpeed}\). \(n \le 1000\).
Fixing hub \(a\), valid nodes in distinct subtrees pair with each other. A DFS counts nodes whose distance from \(a\) is divisible.
For each child of \(a\) the DFS yields \(t\); we add \(s \cdot t\) and then fold \(t\) into \(s\).
First, we construct an adjacency list g based on the edges given in the problem, where g[a] represents all the neighbor nodes of node a and their corresponding edge weights.
Then, we can enumerate each node a as the connecting intermediate node, and calculate the number of nodes t that start from the neighbor node b of a and whose distance to node a can be divided by signalSpeed through depth-first search. Then, the number of connectable node pairs of node a increases by s * t, where s represents the cumulative number of nodes that start from the neighbor node b of a and whose distance to node a cannot be divided by signalSpeed. Then we update s to s + t.
After enumerating all nodes a, we can get the number of connectable node pairs for all nodes.
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\), where \(n\) is the number of nodes.
A pair is counted at hub \(a\) when the two paths share no edge and both distances are divisible by \(\textit{signalSpeed}\). With \(n \le 1000\), valid nodes that lie in different branches of a fixed hub pair with each other. The number of nodes in one branch whose distance from \(a\) is divisible does not depend on visit order, so one walk is enough. Recursing along a chain uses a call depth equal to the node count and overflows Python at \(n = 1000\). The stack therefore stores \((node, parent, distance)\): a divisible distance is counted on pop, and the other neighbors are pushed with the edge weight added. For each neighbor of hub \(a\) this yields a count \(t\); we add \(s \cdot t\) and then fold \(t\) into the running total \(s\).
Build an adjacency list \(g\) from the given edges. \(g[a]\) stores the neighbors of node \(a\) together with the edge weights.
Enumerate each node \(a\) as the hub. For every neighbor \(b\), an explicit stack counts how many nodes in \(b\)'s branch have a distance to \(a\) divisible by \(\textit{signalSpeed}\). Each frame is \((node, parent, distance)\). The walk starts at \(b\) with the weight of edge \((a, b)\). When a frame is popped, a divisible distance increments the count, and every neighbor other than the parent is pushed with that edge weight added to the distance. Let \(s\) be the number of valid nodes already found in earlier branches. Those nodes each pair with the \(t\) nodes of the current branch, so the answer increases by \(s \times t\), and then \(t\) is added to \(s\). The order of the branches does not change the number of pairs.
After every hub has been enumerated, the array holds the number of connectable pairs at each node.
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\), where \(n\) is the number of nodes.