Skip to content

Commit c82da59

Browse files
committed
atcoder/typical90C
1 parent 0982862 commit c82da59

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

atcoder/typical90/C/main.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <bits/stdc++.h>
2+
3+
class TreeDiameter {
4+
private:
5+
struct edge {
6+
size_t to;
7+
uint64_t weight;
8+
};
9+
10+
size_t N;
11+
std::vector<std::vector<edge>> adj;
12+
uint64_t inf;
13+
14+
public:
15+
// Time: O(V)
16+
TreeDiameter(
17+
size_t const N = 0,
18+
uint64_t const inf = std::numeric_limits<uint64_t>::max()
19+
)
20+
: N(N)
21+
, adj(N)
22+
, inf(inf)
23+
{
24+
// Do nothing
25+
}
26+
// Time: O(1)
27+
size_t size() const {
28+
return N;
29+
}
30+
// u = [0,N), v = [0,N), w = [0,inf)
31+
// Time: O(1)
32+
void add_edge(size_t const u, size_t const v, uint64_t const w) {
33+
if (u >= N) throw std::out_of_range("u");
34+
if (v >= N) throw std::out_of_range("u");
35+
if (w >= inf) throw std::out_of_range("w");
36+
adj[u].push_back({ v, w });
37+
adj[v].push_back({ u, w });
38+
}
39+
// s = [0,N)
40+
// Time: O(E)
41+
std::tuple<size_t, size_t, uint64_t> solve(size_t s = 0) const {
42+
size_t u, v;
43+
uint64_t w;
44+
std::tie(u, w) = bfs(s);
45+
std::tie(v, w) = bfs(u);
46+
if (u > v) std::swap(u, v);
47+
return std::make_tuple(u, v, w);
48+
}
49+
50+
private:
51+
std::pair<size_t, uint64_t> bfs(size_t s) const {
52+
std::vector<uint64_t> D(N, inf);
53+
std::queue<size_t> Q;
54+
Q.push(s);
55+
D[s] = 0;
56+
while (Q.size()) {
57+
size_t u = Q.front(); Q.pop();
58+
for (auto const& e : adj[u]) {
59+
if (D[e.to] == inf) {
60+
D[e.to] = D[u] + e.weight;
61+
Q.push(e.to);
62+
}
63+
}
64+
}
65+
size_t v = N;
66+
for (size_t i = 0; i < N; ++i) {
67+
if (D[i] == inf) continue;
68+
if (v == N || D[i] > D[v]) {
69+
v = i;
70+
}
71+
}
72+
return std::make_pair(v, D[v]);
73+
}
74+
};
75+
76+
77+
using namespace std;
78+
using ll = int64_t;
79+
using ff = long double;
80+
81+
int main() {
82+
ios_base::sync_with_stdio(false);
83+
cin.tie(0); cout.tie(0);
84+
85+
int N;
86+
cin >> N;
87+
88+
TreeDiameter solver(N);
89+
for (int i = 0; i < N - 1; i++) {
90+
int A, B;
91+
cin >> A >> B;
92+
--A, --B;
93+
solver.add_edge(A, B, 1);
94+
}
95+
96+
size_t A, B;
97+
uint64_t diameter;
98+
tie(A, B, diameter) = solver.solve();
99+
cout << (diameter + 1) << endl;
100+
101+
return 0;
102+
}

lib/cpalgo/tree/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ We can calculate *Diameter* in `O(V)`. `V` is the number of nodes.
1919
### Challenges
2020
- [Diameter of a Tree - AOJ GRL5A](https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_A)
2121
- [高橋くんと木の直径 - AtCoder ABC019D](https://atcoder.jp/contests/abc019/tasks/abc019_4)
22+
- [003 - Longest Circular Road](https://atcoder.jp/contests/typical90/tasks/typical90_c)
2223

2324
## Height
2425
*Height of a tree* is a max distance between a root node and another node in a tree.

0 commit comments

Comments
 (0)