結果
| 問題 |
No.3206 う し た ウ ニ 木 あ く ん 笑
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-06-12 11:30:06 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 128 ms / 3,000 ms |
| コード長 | 2,444 bytes |
| コンパイル時間 | 2,185 ms |
| コンパイル使用メモリ | 209,460 KB |
| 実行使用メモリ | 35,324 KB |
| 最終ジャッジ日時 | 2025-07-16 01:14:37 |
| 合計ジャッジ時間 | 4,773 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 30 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void search(vector<vector<int>> &tree, vector<pair<int, int>> &dist, int u,
int parent, vector<int> &par) {
par[u] = parent;
int one = 0, two = 0;
if (tree[u].size() == 1 and tree[u][0] == parent) {
dist[u] = {0, 0};
return;
}
for (auto p : tree[u]) {
if (p == parent)
continue;
search(tree, dist, p, u, par);
if (two < dist[p].first + 1) {
two = dist[p].first + 1;
if (two > one)
swap(one, two);
}
}
dist[u] = {one, two};
}
void solve() {
// 各頂点から一番遠い点を保持していればよい。被った時のために二番目まで保持する
int n;
cin >> n;
vector<vector<int>> tree(n + 1);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
tree[u].push_back(v);
tree[v].push_back(u);
}
// 一旦1を頂点とする
vector<int> par(n + 1, -1);
vector<pair<int, int>> dist(n + 1, {-1, -1});
search(tree, dist, 1, -1, par);
int ans = 0;
queue<int> que;
que.push(1);
while (!que.empty()) {
int top = que.front();
que.pop();
vector<int> roads;
// それぞれの子どもについて考えてからpush
for (auto p : tree[top]) {
if (p == par[top])
continue;
que.push(p);
roads.push_back(dist[p].first);
}
if (par[top] != -1) {
// 親が存在するとき、
if (dist[par[top]].first == dist[top].first + 1) {
// 親からの最長経路が自分を通るとき
roads.push_back(dist[par[top]].second);
if (dist[top].second < dist[par[top]].second + 1)
dist[top].second = dist[par[top]].second + 1;
} else {
// 親からの最長経路が自分を通らないとき
roads.push_back(dist[par[top]].first);
if (dist[top].second < dist[par[top]].first + 1)
dist[top].second = dist[par[top]].first + 1;
}
if (dist[top].second > dist[top].first)
swap(dist[top].first, dist[top].second);
}
// ansを更新
sort(roads.begin(), roads.end());
reverse(roads.begin(), roads.end());
for (int i = 0; i < (int)roads.size(); i++) {
ans = max(ans, 1 + (i + 1) * (roads[i] + 1));
}
}
cout << ans << endl;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cout << fixed << setprecision(20);
int CNT = 1;
for (int i = 0; i < CNT; i++)
solve();
}