思路
如果 u , v u, v u,v 两个点直接相连,我们可以直接通过其中一个点的 “以这个结点为根时,所有结点的深度之和” 来推出另一个点的 “以这个结点为根时,所有结点的深度之和” 。
如图:
C
o
d
e
Code
Code
#include <bits/stdc++.h>
#define int long long
#define sz(a) ((int)a.size())
#define all(a) a.begin(), a.end()
using namespace std;
using PII = pair<int, int>;
using i128 = __int128;
const int N = 2e5 + 10;
int n;
void solve() {
cin >> n;
vector<vector<int>> g(n + 1);
for (int i = 1; i <= n - 1; i ++) {
int a, b;
cin >> a >> b;
g[a].push_back(b);
g[b].push_back(a);
}
// root = 1时各个点的深度、每个点的子节点的数量(包括自身)
vector<int> deep(n + 1, -1), num(n + 1, 0);
auto dfs1 = [&] (auto dfs1, int u) ->int {
int total = 1;
for (auto v : g[u]) {
if (deep[v] == -1) {
deep[v] = deep[u] + 1;
total += dfs1(dfs1, v);
}
}
num[u] = total;
return total;
};
deep[1] = 1;
num[1] = n;
dfs1(dfs1, 1);
// 计算以每个点为根节点时的所有节点深度之和
vector <int> sum(n + 1, 0);
for (int i = 1; i <= n; i ++) {
sum[1] += deep[i];
}
auto dfs2 = [&] (auto dfs2, int u) ->void {
for (auto v : g[u]) {
if (sum[v] == 0) {
sum[v] = sum[u] + (n - num[v]) - num[v];
dfs2(dfs2, v);
}
}
};
dfs2(dfs2, 1);
int sum_max = -1, idx = -1;
for (int i = 1; i <= n; i ++) {
if (sum[i] > sum_max) {
sum_max = sum[i];
idx = i;
}
}
cout << " ";
cout << idx << "\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T; cin.get();
while (T --) solve();
return 0;
}