1 条题解

  • 0
    @ 2024-6-28 18:14:33

    问题可以转化为,每个节点上填一个0~m范围内的数字,如果数字非0,则相邻节点的数字不能相同。可以用f[i][0/1]表示节点i 填0/填某非0值 时对应的方案数,则f[i][0]对应的子树v可以填0,可以填1~m,总计为f[v][0]+m*f[v][1]。f[i][1]对应的子树v可以填0,或者1~m范围内并且和i上的数字不同的数字,总计为f[v][0]+(m-1)*f[v][1]。最终答案为f[1][0]+m*f[1][1]

    核心代码
    
    void dfs(int cur, int fa)
    {
        for (int i = 0; i < vec[cur].size(); i++)
        {
            int tar = vec[cur][i];
            if (tar == fa)
                continue;
            dfs(tar, cur);
            f[cur][0] = (f[cur][0] * (f[tar][0] + m * f[tar][1] % mod)) % mod;
            f[cur][1] = (f[cur][1] * (f[tar][0] + (m - 1) * f[tar][1] % mod)) % mod;
        }
    }
    int main()
    {
        cin >> n >> m;
        for (int i = 1; i < n; i++)
        {
            int u, v;
            cin >> u >> v;
            vec[u].push_back(v);
            vec[v].push_back(u);
        }
        for (int i = 1; i <= n; i++)
            f[i][0] = f[i][1] = 1;
        dfs(1, 0);
        cout << (f[1][0] + m * f[1][1] % mod) % mod;
        return 0;
    }
    
    • 1

    信息

    ID
    845
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    (无)
    递交数
    19
    已通过
    10
    上传者