Skip to the content.

:heavy_check_mark: 木の直径
(tree/tree-diameter.hpp)

Verified with

Code

#pragma once

template <class T>
pair<T, vector<int>> TreeDiameter(const vector<vector<pair<int, T>>>& g) {
  int n = g.size();
  assert(n > 0);
  stack<pair<int, int>> st;
  vector<T> d(n);
  st.push({0, -1});
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto [y, w] : g[x]) {
      if (y == p) continue;
      d[y] = d[x] + w;
      st.push({y, x});
    }
  }
  int u = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[u]) u = i;
  d[u] = T{};
  st.push({u, -1});
  vector<int> prv(n, -1);
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto [y, w] : g[x]) {
      if (y == p) continue;
      prv[y] = x;
      d[y] = d[x] + w;
      st.push({y, x});
    }
  }
  int v = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[v]) v = i;
  vector<int> path;
  for (int x = v; x != -1; x = prv[x]) path.push_back(x);
  return {d[v], path};
}
pair<int, vector<int>> TreeDiameter(const vector<vector<int>>& g) {
  int n = g.size();
  assert(n > 0);
  stack<pair<int, int>> st;
  vector<int> d(n);
  st.push({0, -1});
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto y : g[x]) {
      if (y == p) continue;
      d[y] = d[x] + 1;
      st.push({y, x});
    }
  }
  int u = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[u]) u = i;
  d[u] = 0;
  st.push({u, -1});
  vector<int> prv(n, -1);
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto y : g[x]) {
      if (y == p) continue;
      prv[y] = x;
      d[y] = d[x] + 1;
      st.push({y, x});
    }
  }
  int v = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[v]) v = i;
  vector<int> path;
  for (int x = v; x != -1; x = prv[x]) path.push_back(x);
  return {d[v], path};
}
/**
 * @brief 木の直径
 * @docs docs/tree/tree-diameter.md
 */
#line 2 "tree/tree-diameter.hpp"

template <class T>
pair<T, vector<int>> TreeDiameter(const vector<vector<pair<int, T>>>& g) {
  int n = g.size();
  assert(n > 0);
  stack<pair<int, int>> st;
  vector<T> d(n);
  st.push({0, -1});
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto [y, w] : g[x]) {
      if (y == p) continue;
      d[y] = d[x] + w;
      st.push({y, x});
    }
  }
  int u = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[u]) u = i;
  d[u] = T{};
  st.push({u, -1});
  vector<int> prv(n, -1);
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto [y, w] : g[x]) {
      if (y == p) continue;
      prv[y] = x;
      d[y] = d[x] + w;
      st.push({y, x});
    }
  }
  int v = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[v]) v = i;
  vector<int> path;
  for (int x = v; x != -1; x = prv[x]) path.push_back(x);
  return {d[v], path};
}
pair<int, vector<int>> TreeDiameter(const vector<vector<int>>& g) {
  int n = g.size();
  assert(n > 0);
  stack<pair<int, int>> st;
  vector<int> d(n);
  st.push({0, -1});
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto y : g[x]) {
      if (y == p) continue;
      d[y] = d[x] + 1;
      st.push({y, x});
    }
  }
  int u = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[u]) u = i;
  d[u] = 0;
  st.push({u, -1});
  vector<int> prv(n, -1);
  while (!st.empty()) {
    auto [x, p] = st.top();
    st.pop();
    for (auto y : g[x]) {
      if (y == p) continue;
      prv[y] = x;
      d[y] = d[x] + 1;
      st.push({y, x});
    }
  }
  int v = 0;
  for (int i = 1; i < n; i++)
    if (d[i] > d[v]) v = i;
  vector<int> path;
  for (int x = v; x != -1; x = prv[x]) path.push_back(x);
  return {d[v], path};
}
/**
 * @brief 木の直径
 * @docs docs/tree/tree-diameter.md
 */
Back to top page