1 条题解

  • 0
    @ 2026-10-18 18:41:10

    G6026 [GESP202609 六级] 分树规划 题解

    知识点:树遍历、子树大小、最值。

    解题思路

    从根遍历建立父节点与顺序,再逆序累计子树大小。对每条父子边,删除后两部分大小为sz[u]和n-sz[u],取差值绝对值最小。

    为什么正确

    树删一条边恰分成子树与其补集,所有非根节点一一对应全部可删边,因此枚举完备。

    易错点

    根没有父边,不应作为切边候选;先得到孩子的最终大小再合并到父亲。

    复杂度

    时间O(n),空间O(n)。

    参考代码(C++17)

    #include<bits/stdc++.h>
    
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin>>n;
        vector<vector<int>>g(n+1);
        for(int i=1;i<n;i++) {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        vector<int>p(n+1),q= {
            1
        }
        ,sz(n+1,1);
        for(int i=0;i<(int)q.size();i++) {
            int u=q[i];
            for(int v:g[u])if(v!=p[u]) {
                p[v]=u;
                q.push_back(v);
            }
        }
        int ans=n;
        for(int i=n-1;i>0;i--) {
            int u=q[i];
            ans=min(ans,abs(n-2*sz[u]));
            sz[p[u]]+=sz[u];
        }
        cout<<ans;
    }
    

    说明

    本题解为配套教学整理,非官方题解。复杂度按本页参考实现计算,题库使用10个自行生成的测试点。

    • 1

    信息

    ID
    776
    时间
    1000ms
    内存
    512MiB
    难度
    普及−
    标签
    递交数
    0
    已通过
    0
    上传者