TOP > 木 直径
木の直径(Tree-Diameter)
説明
非負の重み付き無向木の直径を求める。適当な頂点 $s$ から最も遠い頂点 $u$ を求める。次に $u$ から最も遠い頂点 $v$ を求める。このとき、($u$, $v$) が最遠頂点対であり、すなわち木の直径である。
計算量
- $O(N)$
実装例
- tree_diameter($g$):= 重み付き無向木 $g$ の直径を求める。
template< typename T >
pair< T, int > dfs(const WeightedGraph< T > &g, int idx, int par) {
pair< T, int > ret(0, idx);
for(auto &e : g[idx]) {
if(e.to == par) continue;
auto cost = dfs(g, e.to, idx);
cost.first += e.cost;
ret = max(ret, cost);
}
return ret;
}
template< typename T >
T tree_diameter(const WeightedGraph< T > &g) {
auto p = dfs(g, 0, -1);
auto q = dfs(g, p.second, -1);
return (q.first);
}
検証
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_A"
#include "../../template/template.cpp"
#include "../../graph/template.cpp"
#include "../tree-diameter.cpp"
int main() {
int N;
scanf("%d", &N);
WeightedGraph< int > g(N);
for(int i = 1; i < N; i++) {
int x, y, z;
scanf("%d %d %d", &x, &y, &z);
g[x].emplace_back(y, z);
g[y].emplace_back(x, z);
}
printf("%d\n", tree_diameter(g));
}