zoukankan      html  css  js  c++  java
  • P3155 [CQOI2009]叶子的染色

      树状dp的实质,我想在我的上一篇博客里总结的挺好的(不知道可以看上一篇qwq)。

      能自己写出来一篇代码并且AC,感觉真不错……

      其实我觉得都不用怎么解释了……

      给出定义:f [ x ] [ y ] 表示把节点 x 染色为 y ,在以 x 为根的子树里最少需要染的点的数量。

      注意一下转移方程,不明白的自己画个图推一推,推不出来的再看看定义,在这里就不解释了。(实在不明白一号机位欢迎你)

      这道题我第三次才过……

      第一次RE了,因为点的数量和边的数量是不一样的,一定要注意。

      第二次是TLE,因为滴bug的时候,只删掉了输出部分,上面的循环忘删了(emmm),所以我的dfs跑了 m - 1 遍……不T才怪呢qwq。

      又想起了ssy曾经和我说的话,题解可以看,但是绝不能抄,那就是欺骗自己。

      最后附上代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    #define maxn 20010
    #define inf 1e9
    int head[maxn],nxt[maxn],to[maxn],out[maxn],f[maxn][3],c[5030];
    int m,n,cnt;
    void add(int a,int b)
    {
        to[++cnt]=b;
        nxt[cnt]=head[a];
        head[a]=cnt;
    }
    void dfs(int v,int fa)
    {
        if(out[v]==1)
        {
            f[v][c[v]]=1;
            f[v][c[v]^1]=inf;
            return ;
        }
        f[v][1]=f[v][0]=1;
        for(int i=head[v];i;i=nxt[i])
        {
            int u=to[i];
            if(u==fa) continue;
            dfs(u,v);
            f[v][0]+=min(f[u][1],f[u][0]-1);
            f[v][1]+=min(f[u][0],f[u][1]-1);
        }
    }
    void Deal_first()
    {
        scanf("%d%d",&m,&n); 
        for(int i=1;i<=n;i++)
        scanf("%d",&c[i]);
        for(int i=1;i<=m-1;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
            out[x]++;
            out[y]++;
        }
    }
    int main()
    {
        Deal_first();
        dfs(n+1,0);
        printf("%d",min(f[n+1][1],f[n+1][0]));
        return 0;
    }
  • 相关阅读:
    Investment_完全背包
    Recaman's Sequence_递推
    MooFest_二维树状数组
    Mobile phones_二维树状数组
    Matrix_二维树状数组
    Get Many Persimmon Trees_枚举&&二维树状数组
    树状数组基础知识
    The Cow Lineup_找规律
    [SOJ] 简单哈希
    sscanf() 函数
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10188107.html
Copyright © 2011-2022 走看看