题目:Codeforces
中文题面:洛谷
分类讨论重心的数量:
怎么找树的重心可以参考:OI Wiki
代码(C++):
#include <iostream>
#include <vector>
using namespace std;
int n;
vector<vector<int>> graph;
vector<int> centroid;
vector<int> siz;
vector<int> weight;
// 寻找一个不为 fa 的点(一条边)
int find(int u, int fa) {
for (int v : graph[u]) {
if (v == fa) {
continue;
}
return v;
}
}
void dfs(int u, int fa) {
siz[u] = 1;
weight[u] = 0;
for (int v : graph[u]) {
if (v == fa) {
continue;
}
dfs(v, u);
siz[u] += siz[v];
weight[u] = max(weight[u], siz[v]);
}
weight[u] = max(weight[u], n - siz[u]);
if (weight[u] <= n / 2) {
centroid[centroid[0] != 0] = u;
}
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
// 二维vector这里一定要清空
graph.clear();
centroid.clear();
graph.resize(n + 1, vector<int>());
centroid.resize(2, 0);
siz.resize(n + 1, 0);
weight.resize(n + 1, 0);
for (int i = 2; i <= n; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
dfs(1, 0);
if (centroid[1] == 0) {
// 只有一个重心的情况
int v = find(centroid[0], centroid[0]);
cout << centroid[0] << " " << v << endl;
cout << centroid[0] << " " << v << endl;
} else {
int v = find(centroid[0], centroid[1]);
cout << centroid[0] << " " << v << endl;
cout << centroid[1] << " " << v << endl;
}
}
return 0;
}
PS:写这个是因为感觉洛谷里的题解个人看着有点复杂。