From c82da59f310a28ab9d47bef06b54129f036a77e5 Mon Sep 17 00:00:00 2001 From: Taichi Yamakawa Date: Mon, 3 May 2021 23:45:17 +0900 Subject: [PATCH] atcoder/typical90C --- atcoder/typical90/C/main.cpp | 102 +++++++++++++++++++++++++++++++++++ lib/cpalgo/tree/README.md | 1 + 2 files changed, 103 insertions(+) create mode 100644 atcoder/typical90/C/main.cpp diff --git a/atcoder/typical90/C/main.cpp b/atcoder/typical90/C/main.cpp new file mode 100644 index 00000000..1ad5692c --- /dev/null +++ b/atcoder/typical90/C/main.cpp @@ -0,0 +1,102 @@ +#include + +class TreeDiameter { +private: + struct edge { + size_t to; + uint64_t weight; + }; + + size_t N; + std::vector> adj; + uint64_t inf; + +public: + // Time: O(V) + TreeDiameter( + size_t const N = 0, + uint64_t const inf = std::numeric_limits::max() + ) + : N(N) + , adj(N) + , inf(inf) + { + // Do nothing + } + // Time: O(1) + size_t size() const { + return N; + } + // u = [0,N), v = [0,N), w = [0,inf) + // Time: O(1) + void add_edge(size_t const u, size_t const v, uint64_t const w) { + if (u >= N) throw std::out_of_range("u"); + if (v >= N) throw std::out_of_range("u"); + if (w >= inf) throw std::out_of_range("w"); + adj[u].push_back({ v, w }); + adj[v].push_back({ u, w }); + } + // s = [0,N) + // Time: O(E) + std::tuple solve(size_t s = 0) const { + size_t u, v; + uint64_t w; + std::tie(u, w) = bfs(s); + std::tie(v, w) = bfs(u); + if (u > v) std::swap(u, v); + return std::make_tuple(u, v, w); + } + +private: + std::pair bfs(size_t s) const { + std::vector D(N, inf); + std::queue Q; + Q.push(s); + D[s] = 0; + while (Q.size()) { + size_t u = Q.front(); Q.pop(); + for (auto const& e : adj[u]) { + if (D[e.to] == inf) { + D[e.to] = D[u] + e.weight; + Q.push(e.to); + } + } + } + size_t v = N; + for (size_t i = 0; i < N; ++i) { + if (D[i] == inf) continue; + if (v == N || D[i] > D[v]) { + v = i; + } + } + return std::make_pair(v, D[v]); + } +}; + + +using namespace std; +using ll = int64_t; +using ff = long double; + +int main() { + ios_base::sync_with_stdio(false); + cin.tie(0); cout.tie(0); + + int N; + cin >> N; + + TreeDiameter solver(N); + for (int i = 0; i < N - 1; i++) { + int A, B; + cin >> A >> B; + --A, --B; + solver.add_edge(A, B, 1); + } + + size_t A, B; + uint64_t diameter; + tie(A, B, diameter) = solver.solve(); + cout << (diameter + 1) << endl; + + return 0; +} \ No newline at end of file diff --git a/lib/cpalgo/tree/README.md b/lib/cpalgo/tree/README.md index 3fe958c1..e09f1515 100644 --- a/lib/cpalgo/tree/README.md +++ b/lib/cpalgo/tree/README.md @@ -19,6 +19,7 @@ We can calculate *Diameter* in `O(V)`. `V` is the number of nodes. ### Challenges - [Diameter of a Tree - AOJ GRL5A](https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_A) - [高橋くんと木の直径 - AtCoder ABC019D](https://atcoder.jp/contests/abc019/tasks/abc019_4) +- [003 - Longest Circular Road](https://atcoder.jp/contests/typical90/tasks/typical90_c) ## Height *Height of a tree* is a max distance between a root node and another node in a tree.