Finding pairs#11609

Finding pairs (Çözgüdiň düşündirişi)

The condition d(i, j) = d(i, 1) - d(j, 1) holds for every pair of vertices where is an ancestor of in the depth-first search starting from vertex .

Let us consider an example:

Let us define the depth of a vertex as the number of vertices on the path from the root (vertex ) to . In the diagram, the depth is written next to each vertex.

Now, fix a vertex and ask the question: how many vertices are there such that the condition d(i, j) = d(i, 1) - d(j, 1) is satisfied?

For example, for i = 6, there are such vertices: j = 1, 3, 4, 6. Note that h[6] = 4. Thus, for a fixed vertex , there are exactly suitable vertices .

To solve the problem, we need to compute the depth for each vertex in the tree, and then find the sum of all these depths across the tree.

Example

Let us consider the graph from the example. Next to each vertex, we write its depth.

The sum of the depths of all vertices is 1 + 2 + 3 + 3 + 4 = 13.

Algorithm implementation

Define the graph's adjacency list as . The depths of the vertices are stored in the array .

vector<vector<int> > g;
vector<int> h;

The dfs function computes the depth of each vertex . The parent of vertex is the vertex .

int dfs(int v, int p)
{
  for (int to : g[v])

Consider the edge (v, to). If the vertex is not the parent of vertex , compute its depth and perform a depth first search starting from it.

    if (to != p)
    {
      h[to] = h[v] + 1;
      dfs(to, v);
    }
  return h[v];
}

The main part of the program. Read the number of vertices in the tree.

scanf("%d", &n);
g.resize(n + 1);

Construct a tree.

for (i = 2; i <= n; i++)
{
  scanf("%d %d", &a, &b);
  g[a].push_back(b);
  g[b].push_back(a);
}

Set the depth of vertex to be .

h.resize(n + 1);
h[1] = 1;

Start a depth first search from the vertex .

dfs(1, -1);

Compute the answer — the sum of the depths of all vertices.

res = 0;
for (i = 1; i <= n; i++)
  res += h[i];

Print the answer.

printf("%lld\n", res);