社区讨论
lca 板子题求助
P3884[JLOI2009] 二叉树问题参与者 4已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @m22y1ifq
- 此快照首次捕获于
- 2024/10/10 14:54 去年
- 此快照最后确认于
- 2025/11/04 17:31 4 个月前
我是求出深度, 记录出相同深度数量的最大值得到宽度, 用 得到距离公式 这样做会有什么问题呢?
CPP
#include <bits/stdc++.h>
using i64 = long long;
void solve() {
int n;
std::cin >> n;
std::vector<std::vector<int>> adj(n);
for (int i = 1; i < n; ++i) {
int u, v;
std::cin >> u >> v;
--u, --v;
adj[u].emplace_back(v);
adj[v].emplace_back(u);
}
const int T = std::__lg(n) + 2;
std::vector<std::vector<int>> fa(n, std::vector<int>(T));
std::vector<int> d(n);
{
auto dfs = [&](auto&& self, int x, int f)->void {
for (auto& y : adj[x]) {
if (y == f) continue;
d[y] = d[x] + 1;
fa[y][0] = x;
self(self, y, x);
}
};
dfs(dfs, 0, -1);
}
{
std::queue<int> q;
q.emplace(0);
std::vector<int> st(n);
while (q.size()) {
auto x = q.front();
q.pop();
if (st[x]) continue;
st[x] = 1;
for (int i = T - 1; i >= 1; --i) {
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for (auto& y : adj[x]) {
q.emplace(y);
}
}
}
int s, t;
std::cin >> s >> t;
--s, --t;
/*for (int i = 0; i < n; ++i) {
for (int j = 0; j < T; ++j) {
std::cout << fa[i][j] << " ";
}
std::cout << '\n';
}*/
auto lca = [&](int l, int r)->int {
if (d[l] < d[r]) std::swap(l, r);
for (int i = T - 1; i >= 0; --i) {
if (d[fa[l][i]] >= d[r]) {
l = fa[l][i];
}
}
if (l == r) {
return l;
}
for (int i = T - 1; i >= 0; --i) {
if (fa[l][i] != fa[r][i]) {
l = fa[l][i];
r = fa[r][i];
}
}
return fa[l][0];
};
int F = lca(s, t);
int deep = std::ranges::max(d);
int Lca = 2 * (d[s] - d[F]) + (d[t] - d[F]);
std::vector<int> cnt(deep + 1);
for (int i = 0; i < n; ++i) {
++cnt[d[i]];
}
std::cout << deep + 1 << "\n" << std::ranges::max(cnt) << "\n" << Lca << '\n';
}
int main() {
int t = 1;
//std::cin >> t;
while (t --)
solve();
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...