求大佬看下写假了没,码风良好
查看原帖
求大佬看下写假了没,码风良好
784813
SakurajiamaMai楼主2024/5/17 16:00
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, p;
    cin >> n >> p;
    p = n - p;
    vector<int> g[n + 1];
    for (int i = 1; i < n; i++)
    {
        int a, b;
        cin >> a >> b;
        g[a].push_back(b);
    }
    vector<int> sz(n + 1);
    function<void(int, int)> dfs;
    vector<int> dp(p + 1, 1e8); // 这里表示的是删去某个大小最小需要用多少条边
    int res = 1e8;
    dp[0] = 0;
    dfs = [&](int u, int fa) -> void
    {
        sz[u] = 1;
        for (auto x : g[u])
        {
            if (x == fa) continue;
            dfs(x, u);
            sz[u] += sz[x];
        }
        vector<int> _(p + 1, 1e9); // 这里表示以当前节点为根节点,然后删去外层只考虑子树部分
        _[0] = 0;
        for (auto x : g[u])
        {
            if (x == fa) continue;
            for (int j = p; j >= sz[x]; j--)
            {
                dp[j] = min(dp[j], dp[j - sz[x]] + 1);
                _[j] = min(_[j], _[j - sz[x]] + 1);
            }
        }
        res = min(res, dp[p]);
        // 如果外层的大小小于等于需要删除的,那么就可以以当前节点为根节点,只考虑自己子树部分,对于外层只需要一下剪断即可
        if (p - n + sz[u] >= 0)
            res = min(res, _[p - n + sz[u]] + 1);
    };
    dfs(1, -1);
    cout << res << '\n';
    return 0;
}

2024/5/17 16:00
加载中...