the center of the tree
Given a tree, the tree contains n nodes (numbered 1~n) and n−1 undirected edges, and each edge has a weight. Please find a point in the tree such that the furthest distance from this point to other nodes in the tree is the shortest.
input format
The first line contains the integer n
Next n−1 lines, each line contains three integers ai, bi, ci, indicating that there is an edge with weight ci between points ai and bi.
output format
Output an integer representing the farthest distance from the requested point to other nodes in the tree.
data range
1≤n≤10000
1≤ai,bi≤n
1≤ci≤105
Input sample:
5
2 1 1
3 2 1
4 3 1
5 1 1
Sample output:
2
Solution
The code above is a C++ program that finds the center of a tree using DFS (depth-first search). The program reads in the number of nodes in the tree from the standard input, followed by the edges and weights of the tree.
The program starts by defining a constant integer N
with a value of 100010, which represents the maximum number of nodes in the tree. It then defines an integer n
to store the number of nodes in the tree, and three integer arrays d1
, d2
, and p1
of size N
to store the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node, respectively. It also defines an integer array up
of size N
to store the maximum distance from each node to the center of the tree.
Next, the program defines a struct Edge
that represents an edge in the tree. The Edge
struct has two integer members: to
, which represents the index of the node that the edge points to, and w
, which represents the weight of the edge.
The program then defines a vector of Edge
objects G
of size N
to represent the adjacency list of the tree.
The program then defines a function named dfs_d
that implements the DFS algorithm to compute the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node. The function takes two arguments: an integer u
representing the current node, and an integer father
representing the parent of the current node. The function iterates over the children of the current node, and recursively calls itself on each child, passing the current node as the parent. For each child, the function computes the distance from the child to the current node, and updates d1
, d2
, and p1
accordingly.
The program then defines a function named dfs_u
that implements the DFS algorithm to compute the maximum distance from each node to the center of the tree. The function takes two arguments: an integer u
representing the current node, and an integer father
representing the parent of the current node. The function iterates over the children of the current node, and recursively calls itself on each child, passing the current node as the parent. For each child, the function computes the maximum distance from the child to the center of the tree, and updates up
accordingly.
In the main
function, the program reads in the number of nodes in the tree from the standard input, and then reads in the edges and weights of the tree. For each edge, the program adds the edge to the adjacency list of the tree.
The program then calls the dfs_d
function on the root node with a parent of 0, which computes the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node. The program then calls the dfs_u
function on the root node with a parent of 0, which computes the maximum distance from each node to the center of the tree.
Finally, the program prints the indices of the nodes that are centers of the tree to the standard output.
Overall, the program finds the center of a tree using DFS by computing the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node, and then computing the maximum distance from each node to the center of the tree.
int dfs_d(int u, int father) {
for (auto x : G[u]) {
if (x.to == father) continue;
int d = dfs_d(x.to, u) + x.w;
if (d > d1[u]) {
d2[u] = d1[u], d1[u] = d;
p1[u] = x.to;
}else if (d > d2[u]) d2[u] = d;
}
return d1[u];
}
The code above is a C++ function named dfs_d
that implements the DFS algorithm to compute the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node. The function takes two arguments: an integer u
representing the current node, and an integer father
representing the parent of the current node.
The function starts by iterating over the children of the current node using a range-based for loop that iterates over the adjacency list of the current node stored in the vector G
. For each child, the function checks if the child is the same as the parent, and if so, skips the child using the continue
statement.
For each non-parent child, the function recursively calls itself on the child, passing the current node as the parent. The function then computes the distance from the child to the current node by adding the weight of the edge connecting the child to the current node to the distance from the child to its parent. The function then updates the maximum and second maximum distances from the current node to its children, and the parent of the child that is farthest from the node, stored in the arrays d1
, d2
, and p1
, respectively, based on the computed distance. If the computed distance is greater than the current maximum distance from the current node to its children, the current maximum distance becomes the second maximum distance, and the computed distance becomes the new maximum distance. The parent of the child that is farthest from the node is also updated to be the child that was just processed. If the computed distance is greater than the current second maximum distance from the current node to its children, the computed distance becomes the new second maximum distance.
Finally, the function returns the maximum distance from the current node to its children.
Overall, the dfs_d
function computes the maximum and second maximum distances from each node to its children, and the parent of the child that is farthest from the node, using DFS by iterating over the children of each node, recursively calling itself on each child, and updating the maximum and second maximum distances and the parent of the child that is farthest from the node based on the computed distance.
void dfs_u(int u, int father) {
for (auto x : G[u]) {
if (x.to == father) continue;
if (p1[u] == x.to) up[x.to] = max(up[u], d2[u]) + x.w;
else up[x.to] = max(up[u], d1[u]) + x.w;
dfs_u(x.to, u);
}
}
The code above is a C++ function named dfs_u
that implements the DFS algorithm to compute the maximum distance from each node to the center of a tree. The function takes two arguments: an integer u
representing the current node, and an integer father
representing the parent of the current node.
The function starts by iterating over the children of the current node using a range-based for loop that iterates over the adjacency list of the current node stored in the vector G
. For each child, the function checks if the child is the same as the parent, and if so, skips the child using the continue
statement.
For each non-parent child, the function computes the maximum distance from the child to the center of the tree using the following logic. If the child is the child that is farthest from the current node, as determined by the parent of the child stored in the array p1
, then the maximum distance from the child to the center of the tree is the maximum of the maximum distance from the current node to the center of the tree and the second maximum distance from the current node to its children, plus the weight of the edge connecting the current node to the child. This is computed using the expression up[x.to] = max(up[u], d2[u]) + x.w;
. If the child is not the child that is farthest from the current node, then the maximum distance from the child to the center of the tree is the maximum of the maximum distance from the current node to the center of the tree and the maximum distance from the current node to the child, plus the weight of the edge connecting the current node to the child. This is computed using the expression up[x.to] = max(up[u], d1[u]) + x.w;
.
Finally, the function recursively calls itself on each child, passing the current node as the parent.
Overall, the dfs_u
function computes the maximum distance from each node to the center of a tree using DFS by iterating over the children of each node, computing the maximum distance from each child to the center of the tree, and recursively calling itself on each child.
#include <bits/stdc++.h>
using namespace std;
const int N = 10010, INF = 0x3f3f3f3f;
int n;
struct Edge {
int to, w;
};
int d1[N], d2[N], p1[N], up[N];
vector<Edge> G[N];
int dfs_d(int u, int father) {
for (auto x : G[u]) {
if (x.to == father) continue;
int d = dfs_d(x.to, u) + x.w;
if (d > d1[u]) {
d2[u] = d1[u], d1[u] = d;
p1[u] = x.to;
}else if (d > d2[u]) d2[u] = d;
}
return d1[u];
}
void dfs_u(int u, int father) {
for (auto x : G[u]) {
if (x.to == father) continue;
if (p1[u] == x.to) up[x.to] = max(up[u], d2[u]) + x.w;
else up[x.to] = max(up[u], d1[u]) + x.w;
dfs_u(x.to, u);
}
}
int main() {
cin.tie(nullptr);
cout.tie(nullptr);
ios::sync_with_stdio(false);
cin >> n;
for (int i = 0; i < n - 1; i ++ ) {
int a, b, w;
cin >> a >> b >> w;
G[a].push_back({b, w}), G[b].push_back({a, w});
}
dfs_d(1, 0);
dfs_u(1, 0);
int ans = INF;
for (int i = 1; i <= n; i ++ ) ans = min(ans, max(up[i], d1[i]));
cout << ans << endl;
return 0;
}