This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_5_A"
#include "../Graph/centroid_decomposition.hpp"
#include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
int main() {
std::cin.tie();
std::ios::sync_with_stdio(false);
int n;
std::cin >> n;
Graph<int> graph(n);
for (int i = 0; i < n - 1; ++i) {
int u, v, w;
std::cin >> u >> v >> w;
graph.span(false, u, v, w);
}
Centroid<int> cent(graph);
int ans = 0;
std::queue<int> cents;
cents.push(0);
std::vector<int> dist(n);
while (!cents.empty()) {
int r = cents.front();
cents.pop();
r = cent.find(r);
cent.deleted[r] = true;
std::vector<int> fars({0, 0});
for (auto e : graph[r]) {
if (cent.deleted[e.dst]) continue;
cents.push(e.dst);
// BFS
std::queue<std::pair<int, int>> que;
que.emplace(e.dst, -1);
dist[e.dst] = e.cost;
int far = 0;
while (!que.empty()) {
int v, p;
std::tie(v, p) = que.front();
que.pop();
far = std::max(far, dist[v]);
for (auto f : graph[v]) {
if (f.dst == p || cent.deleted[f.dst]) continue;
dist[f.dst] = dist[v] + f.cost;
que.emplace(f.dst, v);
}
}
fars.push_back(far);
}
std::sort(fars.rbegin(), fars.rend());
if (fars.size() >= 2) ans = std::max(ans, fars[0] + fars[1]);
}
std::cout << ans << "\n";
return 0;
}#line 1 "Verify/centroid_decomposition_diameter.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_5_A"
#line 2 "Graph/centroid_decomposition.hpp"
#line 2 "Graph/graph.hpp"
#include <vector>
template <class Cost = int>
struct Edge {
int src, dst;
Cost cost;
Edge() = default;
Edge(int src, int dst, Cost cost = 1)
: src(src), dst(dst), cost(cost){};
bool operator<(const Edge<Cost>& e) const { return cost < e.cost; }
bool operator>(const Edge<Cost>& e) const { return cost > e.cost; }
};
template <class Cost = int>
struct Graph : public std::vector<std::vector<Edge<Cost>>> {
using std::vector<std::vector<Edge<Cost>>>::vector;
void span(bool direct, int src, int dst, Cost cost = 1) {
(*this)[src].emplace_back(src, dst, cost);
if (!direct) (*this)[dst].emplace_back(dst, src, cost);
}
};
#line 4 "Graph/centroid_decomposition.hpp"
template <class Cost = int>
struct Centroid {
Graph<Cost> graph;
std::vector<bool> deleted;
std::vector<int> sz;
explicit Centroid(const Graph<Cost>& graph)
: graph(graph), deleted(graph.size(), false), sz(graph.size()) {}
int szdfs(int v, int p = -1) {
sz[v] = 1;
for (auto e : graph[v]) {
if (e.dst == p || deleted[e.dst]) continue;
sz[v] += szdfs(e.dst, v);
}
return sz[v];
}
int find(int v) {
int n = szdfs(v);
int p = -1;
while (true) {
int nxt = -1;
for (auto e : graph[v]) {
if (e.dst == p || deleted[e.dst]) continue;
if (nxt == -1 || sz[e.dst] > sz[nxt]) nxt = e.dst;
}
if (nxt == -1 || sz[nxt] <= n / 2) return v;
p = v;
v = nxt;
}
}
};
#line 4 "Verify/centroid_decomposition_diameter.test.cpp"
#include <iostream>
#include <algorithm>
#include <queue>
#include <tuple>
int main() {
std::cin.tie();
std::ios::sync_with_stdio(false);
int n;
std::cin >> n;
Graph<int> graph(n);
for (int i = 0; i < n - 1; ++i) {
int u, v, w;
std::cin >> u >> v >> w;
graph.span(false, u, v, w);
}
Centroid<int> cent(graph);
int ans = 0;
std::queue<int> cents;
cents.push(0);
std::vector<int> dist(n);
while (!cents.empty()) {
int r = cents.front();
cents.pop();
r = cent.find(r);
cent.deleted[r] = true;
std::vector<int> fars({0, 0});
for (auto e : graph[r]) {
if (cent.deleted[e.dst]) continue;
cents.push(e.dst);
// BFS
std::queue<std::pair<int, int>> que;
que.emplace(e.dst, -1);
dist[e.dst] = e.cost;
int far = 0;
while (!que.empty()) {
int v, p;
std::tie(v, p) = que.front();
que.pop();
far = std::max(far, dist[v]);
for (auto f : graph[v]) {
if (f.dst == p || cent.deleted[f.dst]) continue;
dist[f.dst] = dist[v] + f.cost;
que.emplace(f.dst, v);
}
}
fars.push_back(far);
}
std::sort(fars.rbegin(), fars.rend());
if (fars.size() >= 2) ans = std::max(ans, fars[0] + fars[1]);
}
std::cout << ans << "\n";
return 0;
}