日常刷题2025-2-27
易错点multiset删除元素
使用multiset删除容器中的一个元素时,如果直接erase(a),则会把multiset中所有等于a的元素全部删除。
如果想要达到的效果是只删除一个,则需要这么使用
std::multiset<int> st;
int a;
st.erase(st.find(a));
I 图中最深的根
思路:换根DP
当题目提到要考查每一个节点作为根节点时的最大高度时,已经很明显的在暗示使用换根DP了。
此题就是最正常的换根DP,没有什么小巧思
#include <bits/stdc++.h>typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5 + 5;struct DSU {std::vector<int> f, siz;DSU() {}DSU(int n) {init(n);}void init(int n) {f.resize(n);std::iota(f.begin(), f.end(), 0);siz.assign(n, 1);}int find(int x) {while (x != f[x]) {x = f[x] = f[f[x]];}return x;}bool same(int x, int y) {return find(x) == find(y);}bool merge(int x, int y) {x = find(x);y = find(y);if (x == y) {return false;}siz[x] += siz[y];f[y] = x;return true;}int size(int x) {return siz[find(x)];}
};void solve() {int n;std::cin >> n;DSU dsu(n);int cm = n;std::vector g(n, std::vector<int>());for (int i = 0; i < n - 1; i++) {int u, v;std::cin >> u >> v;u--, v--;g[u].push_back(v);g[v].push_back(u);if (!dsu.same(u, v)) {dsu.merge(u, v);cm--;}}if (cm >= 2) {std::cout << "Error: " << cm << " components\n";return;}std::vector<int> f(n), gg(n), dp(n);auto dfs1 = [&](auto self, int cur, int fa) -> void {int mx = 0;for (auto to : g[cur]) {if (to == fa) continue;self(self, to, cur);mx = std::max(mx, f[to]);}f[cur] = mx + 1;};dp[0] = 0;auto dfs2 = [&](auto self, int cur, int fa) -> void {std::multiset<int> st;for (auto to : g[cur]) {if (to == fa) continue;st.insert(f[to]);}for (auto to : g[cur]) {if (to == fa) continue;st.erase(st.find(f[to]));int mx = 0;if (st.size() == 0) {mx = 0;} else {mx = *st.rbegin();}dp[to] = std::max(mx, dp[cur]) + 1;st.insert(f[to]);self(self, to, cur);}};dfs1(dfs1, 0, -1);dfs2(dfs2, 0, -1);for (int i = 0; i < n; i++) {gg[i] = std::max(f[i] - 1, dp[i]) + 1;}int mx = *std::max_element(gg.begin(), gg.end());for (int i = 0; i < n; i++) {if (gg[i] == mx) {std::cout << i + 1 << '\n';}}
}signed main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);int t = 1;for (int i = 0; i < t; i++) {solve();}return 0;
}