Longest path in a tree#10050

Longest path in a tree (Editorial)

The shortest path in a weighted tree can be found using either depth-first search or breadth-first search; using Dijkstra’s algorithm is not necessary in this case.

To find the longest path (the diameter of the tree), proceed as follows:

  1. Perform a breadth-first search starting from the first vertex. Identify the vertex , which has the longest path from the starting vertex.

  2. Next, perform a breadth-first search starting from vertex to find the vertex u, which also has the longest path from .

  3. The path from to is the longest path in the tree (the tree's diameter).

Example

The tree shown in the example has the following structure:

Algorithm implementation

Declare the adjacency list of the graph .

Declare the array of shortest distances .

vector<vector<pair<int, int>> > g;
vector<long long> d;

The function bfs performs a breadth-first search starting from vertex .

int bfs(int v)
{
  deque<int> q;
  q.push_back(v);
  while (!q.empty())
  {
    int v = q.front(); q.pop_front();
    for (auto x : g[v])
    {
      int to = x.first;
      int w = x.second;
      if (d[to] == -1)
      {
        d[to] = d[v] + w;
        q.push_back(to);
      }
    }
  }

Return the number of the vertex to which the distance from vertex is maximal.

  return max_element(d.begin() + 1, d.begin() + n + 1) - d.begin();
}

The main part of the program. Read the input data. Build the graph.

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

for (i = 0; i < n - 1; i++)
{
  scanf("%d %d %lld", &b, &e, &dist);
  g[b].push_back({ e, dist });
  g[e].push_back({ b, dist });
}

Initialize the array of shortest distances.

d = vector<long long>(n + 1, -1);
d[1] = 0;

Perform the first breadth-first search starting from vertex . Identify the vertex that is farthest from vertex .

int v = bfs(1);

Re-initialize the array of shortest distances and perform the second breadth-first search starting from vertex .

d = vector<long long>(n + 1, -1);
d[v] = 0;
v = bfs(v);

Print the result — the length of the longest path.

printf("%lld\n", d[v]);

Algorithm implementation — depth first serch

The adjacency list of the graph is stored in the array .

To store the shortest distances, declare the array .

vector<vector<pair<int, int>> > g;
vector<long long> dist;

The function dfs performs a depth-first search starting from vertex . Vertex is the parent of during the depth-first search.

void dfs(int v, int p = -1)
{

Iterate over all edges adjacent to vertex .

  for (auto x : g[v])
  {

Consider the edge v → to with weight .

    int to = x.first;
    int w = x.second;

If to \ne p, update dist[to] and perform a depth-first search starting from vertex .

    if (to != p)
    {
      dist[to] = dist[v] + w;
      dfs(to, v);
    }
  }
}

The main part of the program. Read the input data. Build the graph.

scanf("%d", &n);
g.resize(n + 1);
for (i = 0; i < n - 1; i++)
{
  scanf("%d %d %d", &b, &e, &w);
  g[b].push_back({ e, w });
  g[e].push_back({ b, w });
}

Perform a depth-first search starting from vertex . Fill the array of shortest distances from vertex .

dist.assign(n + 1, -1);
dist[1] = 0;
dfs(1);

Find vertex , which is the farthest from vertex .

v = max_element(dist.begin(), dist.end()) - dist.begin();

Perform a second depth-first search starting from vertex . Fill the array of shortest distances from vertex .

dist.assign(n + 1, -1);
dist[v] = 0;
dfs(v);

The largest value in the array is equal to the diameter of the tree.

v = max_element(dist.begin(), dist.end()) - dist.begin();

Print the answer.

printf("%lld\n", dist[v]);

Python implementation

from collections import deque

Read the input data. Store the adjacency list of the graph in .

Declare a list of shortest distances .

n = int(input())
g = [[] for _ in range(n + 1)]
d = [-1] * (n + 1)

Construct a graph.

for _ in range(n - 1):
  b, e, dist = map(int, input().split())
  g[b].append((e, dist))
  g[e].append((b, dist))

The function bfs performs a breadth-first search starting from vertex .

def bfs(v):
  q = deque()
  q.append(v)

  while q:
    v = q.popleft()
    for to, w in g[v]:
      if d[to] == -1:
        d[to] = d[v] + w
        q.append(to)

Return the number of the vertex that is farthest from vertex .

  return d.index(max(d))

Perform the first breadth-first search from vertex . Determine the vertex that is the farthest from vertex .

d[1] = 0
v = bfs(1)

Initialize the array of shortest distances and perform the second breadth-first search from vertex .

d = [-1] * (n + 1)
d[v] = 0
v = bfs(v)

Print the answer — the length of the longest path.

print(d[v])