1 条题解

  • 0
    @ 2026-10-26 14:35:24

    思路与算法

    任选一个非叶节点为根。可以把问题化为给所有节点补上黑白标签,叶子的标签固定,最小化不同标签相邻边的数量,再加1。dp[u][c]表示u标签为c时子树最少变色边;孩子v贡献min(dp[v][c],dp[v][1-c]+1)。用迭代遍历反序计算,答案1+min根的两个状态。

    正确性说明

    给根涂色,再在每条变色边的孩子处涂新色,就可实现对应叶色,涂色数等于1+变色边数。反过来,无意义的同色重复涂色可删除;若原根未涂,可选择一个分支最先涂的颜色给根,并移除该分支的首次同色涂色,不增加数量。因此存在这种根涂色的最优方案。固定节点颜色后各孩子子树独立,递推精确;最少变色边与根位置无关。

    复杂度

    建邻接表与遍历O(m),两状态转移O(m),空间O(m),包括树、父亲、遍历序与dp。全部数组初始化O(m)。最多1万节点,不用递归,防止深链爆栈。

    易错点

    编号1至n是给定颜色的叶子,不要按输入边顺序猜叶子。根必须为非叶,代码取第一个非叶编号n+1。相同叶色全树只涂1点;两种颜色的星形可选中心多数色。独立小图枚举全部3态涂色和全部合法根,满规模用星形及长链的精确答案。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int m, n;
        cin >> m >> n;
        vector<int> color(n);
        for (int &x : color)
            cin >> x;
        vector<vector<int>> g(m);
        for (int i = 1, a, b; i < m; ++i) {
            cin >> a >> b;
            --a;
            --b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        int root = n;
        vector<int> parent(m, -1), order(1, root);
        for (size_t i = 0; i < order.size(); ++i) {
            int u = order[i];
            for (int v : g[u])
                if (v != parent[u]) {
                    parent[v] = u;
                    order.push_back(v);
                }
        }
        vector<array<int, 2>> dp(m);
        int INF = m + 1;
        for (auto it = order.rbegin(); it != order.rend(); ++it) {
            int u = *it;
            if (u < n) {
                dp[u][color[u]] = 0;
                dp[u][1 - color[u]] = INF;
            } else
                for (int c = 0; c < 2; ++c)
                    for (int v : g[u])
                        if (parent[v] == u)
                            dp[u][c] += min(dp[v][c], dp[v][1 - c] + 1);
        }
        cout << 1 + min(dp[root][0], dp[root][1]) << '\n';
    }
    
    • 1

    信息

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