Codeforces Round 1000 (Div. 2)-C题(树上两个节点不同边数最大值)
https://codeforces.com/contest/2063/problem/C
牢记一棵树上两个节点如果相邻,它们有一条边会重叠,两个节点延伸出去的所有不同边是两个节点入度之和-1而不是入度之和,那么如果这棵树上有三个节点它们的入度都相同,那么优先选择非相邻的两个节点才能使所有不同边的数量最大!!
然后思路就是:暴力
template<class Info>
struct SegmentTree {
int n;
std::vector<Info> info;
SegmentTree() : n(0) {}
SegmentTree(int n_, Info v_ = Info()) {
init(n_, v_);
}
template<class T>
SegmentTree(std::vector<T> init_) {
init(init_);
}
void init(int n_, Info v_ = Info()) {
init(std::vector(n_, v_));
}
template<class T>
void init(std::vector<T> init_) {
n = init_.size();
info.assign(4 << (int)std::log2(n), Info());
std::function<void(int, int, int)> build = [&](int p, int l, int r) {
if (r - l == 1) {
info[p] = init_[l];
return;
}
int m = (l + r) / 2;
build(2 * p, l, m);
build(2 * p + 1, m, r);
pull(p);
};
build(1, 0, n);
}
void pull(int p) {
info[p] = info[2 * p] + info[2 * p + 1];
}
void modify(int p, int l, int r, int x, const Info& v) {
if (r - l == 1) {
info[p] = v;
return;
}
int m = (l + r) / 2;
if (x < m) {
modify(2 * p, l, m, x, v);
}
else {
modify(2 * p + 1, m, r, x, v);
}
pull(p);
}
void modify(int p, const Info& v) {
modify(1, 0, n, p, v);
}
Info rangeQuery(int p, int l, int r, int x, int y) {
if (l >= y || r <= x) {
return Info();
}
if (l >= x && r <= y) {
return info[p];
}
int m = (l + r) / 2;
return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
}
Info rangeQuery(int l, int r) {
return rangeQuery(1, 0, n, l, r);
}
};
struct Info {
int max=0;
};
Info operator+(Info a, Info b) {
return { std::max(a.max,b.max) };
}
void solve() {
int n;
std::cin >> n;
std::vector<Info>a(n);
std::vector<std::vector<int>>adj(n);
for (int i = 0; i < n - 1; i++) {
int u, v;
std::cin >> u >> v;
u--;
v--;
a[u].max++;
a[v].max++;
adj[u].push_back(v);
adj[v].push_back(u);
}
SegmentTree<Info>t(a);
int ans = 0;
for (int i = 0; i < n; i++) {
t.modify(i, { 0 });
for (int j = 0; j < adj[i].size(); j++) {
int x = adj[i][j];
t.modify(x, { a[x].max - 1 });
}
ans = std::max(ans, a[i].max + t.rangeQuery(0, n).max);
t.modify(i, { a[i]});
for (int j = 0; j < adj[i].size(); j++) {
int x = adj[i][j];
t.modify(x, { a[x].max });
}
}
std::cout << ans-1 << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
int t = 1;
std::cin >> t;
while (t--) {
solve();
}
return 0;
}
原文地址:https://blog.csdn.net/Colinnian/article/details/145311828
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!