You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N << 1;
#define int long long
#define endl "\n"
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int sz[N]; // sz[i]:以i为根的子树中节点个数
int son[N]; // son[i]:去掉节点i后剩下的连通分量中最大子树节点个数
int r1, r2, n;
void dfs(int u, int fa) {
sz[u] = 1; // u为根的子树中最起码有一个节点u
son[u] = 0; // 把节点u去掉后剩下的连通分量中最大子树节点个数现在还不知道预求最大先设最小
for (int i = h[u]; ~i; i = ne[i]) { // 枚举u的每一条出边
int v = e[i];
if (v == fa) continue;
dfs(v, u); // 先把v为根的子树遍历完
sz[u] += sz[v]; // 把 v中获取填充的sz[v]值用于组装自己sz[u]
son[u] = max(son[u], sz[v]); // 如果把u节点去掉那么它的所有子节点v为根的子树中节点数可以参加评选
// 评选的标准是son[i]:去掉节点i后剩下的连通分量中最大子树节点个数
}
son[u] = max(son[u], n - sz[u]); // 右上角的那一块也可能成为评选的获胜者
if ((son[u] << 1) <= n) r2 = r1, r1 = u; // 删除重心后所得的所有子树节点数不超过原树的1/2一棵树最多有两个重心
// 如果模拟u被删除后得到的所有子树中节点数量最多的没有超过原树的1/2,那么这个r1=u表示找到了一个重心u
// r2=r1表示如果找到两个重心那么r1,r2 一人一个此时r1中肯定有值但 r2不一定有值
}
signed main() {
int T;
cin >> T;
while (T--) {
cin >> n;
// 多组测试数据,清空
memset(sz, 0, sizeof sz);
memset(son, 0, sizeof son);
// 初始化链式前向星
memset(h, -1, sizeof h);
idx = 0;
r1 = r2 = 0;
for (int i = 1; i < n; i++) { // n-1条边
int x, y;
cin >> x >> y;
add(x, y), add(y, x);
}
dfs(1, 0); // 以1号点为入口它的父节点是0
if (!r2) {
int r3 = e[h[r1]];
cout << r1 << " " << r3 << endl;
cout << r1 << " " << r3 << endl;
} else {
int r3 = r1;
for (int i = h[r2]; ~i; i = ne[i]) {
r3 = e[i];
if (r3 != r1) break;
}
cout << r3 << " " << r2 << endl;
cout << r3 << " " << r1 << endl;
}
}
return 0;
}