1021. Deepest Root (25)
P 判断连通:并查集.找最长的根,两步DFS.第一个DFS从一个点出发,找到里这个点最远的点集合,这个在ANS里面.第二部从ANS里任意找个点,再DFS.又找到最远的点集.两个点集的并集,就是ANS.不要问我为什么,我也不知道.
#include <bits/stdc++.h>
using namespace std;
struct UnionFind
{
vector<int> id, sz;
int n, cnt;
UnionFind(int n) : n(n)
{
id.resize(n);
sz.resize(n);
for (int i = 0; i < n; i++) {
id[i] = i;
sz[i] = 1;
}
cnt = n;
}
int fd(int x)
{
if (x == id[x]) return x;
return id[x] = fd(id[x]);
}
void unite(int x, int y)
{
x = fd(x), y = fd(y);
if (x == y) return;
if (sz[x] < sz[y]) swap(x, y);
id[y] = x;
sz[x] += sz[y];
cnt--;
}
};
vector< vector<int> > g;
set<int> ans;
vector<int> ans2;
int maxh, maxh2;
void dfs(int u, int f, int h)
{
if (h > maxh) {
maxh = h;
ans.clear();
ans.insert(u);
} else if (h == maxh) {
ans.insert(u);
}
for (int v : g[u]) {
if (v == f) continue;
dfs(v, u, h + 1);
}
}
void dfs2(int u, int f, int h)
{
if (h > maxh2) {
maxh2 = h;
ans2.clear();
ans2.push_back(u);
} else if (h == maxh2)
{
ans2.push_back(u);
}
for (int v : g[u]) {
if (v == f) continue;
dfs2(v, u, h + 1);
}
}
int main()
{
//freopen("in", "r", stdin);
int N;
scanf("%d", &N);
UnionFind uf(N);
g.resize(N);
maxh = 0;
for (int i = 0; i < N - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
u--, v--;
g[u].push_back(v);
g[v].push_back(u);
uf.unite(u, v);
}
if (uf.cnt > 1) {
printf("Error: %d components\n", uf.cnt);
return 0;
}
dfs(0, -1, 0);
maxh2 = 0;
dfs2(*ans.begin(), -1, 0);
for (int e : ans2) {
ans.insert(e);
}
for (int e : ans) {
cout << e + 1 << endl;
}
}