2 条题解

  • 0
    @ 2025-10-8 17:03:39
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e4+10;
    vector<int>G[N];
    int m,n,c[N],f[N][2];
    /*
    f[x][k]表示x结点染成k色使得x子树合法的最小染色数。
    可以想到如果x的孩子y染了k色,那么y的k色完全可以染在x上,不需要染v,可以得到转移方程。 
    f[x][0]+=min(f[y][0]-1,f[y][1]);
    f[x][1]+=min(f[y][1]-1,f[y][0]);
    */
    void dp(int x,int ff)
    {
        if(x<=n) return;
        f[x][0]=f[x][1]=1;
        for(int y:G[x])if(y!=ff)
    	{
            dp(y,x);
            f[x][0]+=min(f[y][0]-1,f[y][1]);
            f[x][1]+=min(f[y][1]-1,f[y][0]);
        }
    }
    int main()
    {
        scanf("%d%d",&m,&n);
        memset(f,0,sizeof(f));
    	for(int i=1;i<=n;i++){scanf("%d",&c[i]); f[i][c[i]]=1,f[i][!c[i]]=1e9;}
        for(int i=1,x,y;i<m;i++)
        {
            scanf("%d%d",&x,&y);
            G[x].emplace_back(y);
            G[y].emplace_back(x);
        }
        
    	int rt=n+1;
        dp(rt,rt);
        
        printf("%d",min(f[rt][1],f[rt][0]));
        return 0;
    }
    
    • -1
      @ 2026-9-2 21:00:22

      这题真的有绿吗……

      我看完题解之后有一个问题,为何哪一个节点作为根无所谓呢?

      我们考虑两个节点xxyy满足xxyy的父亲,假设原树的子图XX表示以xx为根节点的子树除去以yy为根节点的子树,设yy的子树为YY。我们要证明哪一个节点作为根无所谓等价于证明xx做父亲和yy做父亲是一样的。

      那为何他们是一样的呢?

      不难想到如果XX所需要的颜色与YY所需要的颜色一样,那么只需将父亲染色即可,那个节点作为父亲无所谓;如果所需颜色不一样,那么都需要各自的子树去染色,与父亲节点并无关联。

      综上,哪一个作为根节点并无关系。

      • 1

      *【树形DP】8:[CQOI2009] 叶子的染色

      信息

      ID
      2957
      时间
      1000ms
      内存
      512MiB
      难度
      6
      标签
      递交数
      70
      已通过
      22
      上传者