日常刷题2025-2-27

日常刷题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;
}
posted @ 2025-02-27 16:54  califeee  阅读(40)  评论(0)    收藏  举报