Perform a depth-first search starting from vertex . For each vertex, compute two values:
— the distance from vertex to vertex . If is the parent of , then
— the distance from vertex v to the nearest leaf in the subtree rooted at . If to_1, to_2, ..., to_k are the children of vertex , then
If is a leaf of the tree, set h[v] = 0.
Next, perform a second depth-first search. During this traversal, compute the value — the minimum number of friends that need to be placed in some of the leaves of the subtree rooted at vertex in order to guarantee catching the butterfly, assuming it chooses to fly into this subtree.
If h[v] \le d[v], then res[v] = 1. In this case, it is enough to place one friend in the leaf with the minimal depth in the subtree rooted at vertex : they will reach vertex no later than the butterfly flying from the root.
Otherwise, if to_1, to_2, ..., to_k are the children of vertex , then
If the butterfly is not caught at vertex itself, we must be prepared to intercept it in any of the subtrees of 's children.
The final answer to the problem is the value .
Example
In the first example (shown in the left diagram), two friends are required, and they should be placed at the two exits. The butterfly can fly from vertex either to vertex or to vertex . In either case, it will be intercepted by one of Nyusha's friends.
In the second example (shown in the right diagram), one friend is enough, who can be placed at either of the two exits — vertex or . The butterfly will fly from vertex to vertex in one minute. During that same time, the friend will reach vertex and catch the butterfly there.
Let us consider the next example.
Nyusha will need three friends to catch the butterfly.
Algorithm implementation
Declare a constant for infinity and arrays.
#define INF 2000000000
vector<vector<int> > g;
vector<int> d, h, res;The function dfs (v, p, cnt) performs a depth-first search starting from vertex and returns the value . Here, is the parent of vertex , and cnt is the distance from vertex to . During the traversal, the values and are computed for each vertex .
int dfs(int v, int p = -1, int cnt = 0)
{The value , which equals the distance from vertex to , is stored in .
d[v] = cnt;
int height = INF;Iterate over all the children of the vertex . Consider the edge v \to to. If equals the parent of v~(to = p), skip it and move to the next child.
for (int to : g[v])
if (to != p) In the variable compute the value
where to_1, to_2, ..., to_k are the children of vertex .
If height = INF, then vertex is a leaf, and set h[v] = 0. Otherwise rerturn
return h[v] = (height == INF) ? 0 : 1 + height;
}The function dfs2 performs a depth-first search starting from vertex and returns the value . Here, is the parent of vertex .
int dfs2(int v, int p = -1)
{
int s = 0;Let to_1, to_2, ..., to_k be the children of vertex . In the variable , compute the sum:
for (int to : g[v])
if (to != p)
{
dfs2(to, v);
s += res[to];
}If h[v] \le d[v], then one friend is sufficient, and res[v] = 1. Otherwise
return res[v] = (h[v] <= d[v]) ? 1 : s;
}The main part of the program. Read the input data. Construct a graph.
scanf("%d", &n);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
scanf("%d %d", &a, &b);
g[a].push_back(b);
g[b].push_back(a);
}Initialize the arrays.
d.resize(n + 1);
h.resize(n + 1);
res.resize(n + 1);Run two depth-first searches. The first traversal computes the values of and for each vertex .
dfs(1);
dfs2(1);Print the answer — the minimum number of friends needed to catch the butterfly.
printf("%lld\n", res[1]);