1 条题解

  • 0
    @ 2025-8-24 22:38:44

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar llingy
    凤凰涅槃,向死而生

    搬运于2025-08-24 22:38:44,当前版本为作者最后更新于2023-12-02 22:41:01,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题意简述

    给定一棵 nn 个点的树,点有蓝色和白色两种颜色,每次选择一个蓝点 uu 并将所有距离为 11 的点染成蓝色,代价为该点的点权 wuw_u,求将树全变为蓝色的最小代价。n2×105n\le 2\times 10^5

    思路

    树 DP。

    每个点要么被父亲染成蓝色,要么被儿子染成蓝色。设 fu,0/1/2/3f_{u,0/1/2/3} 为对于 uu 子树内所有节点都被染成蓝色,uu 被选择,父亲需要被选择 / uu 不被选择,父亲需要被选择 / uu 被选择,父亲不需要被选择 / uu 不被选择,父亲不需要被选择。

    uu 下方加入一个儿子 vv。则有转移:

    • 对于 fu,0f_{u,0} 的转移,uu 被选择,则对 vv 不做要求,任意状态均可转移。$f_{u,0}\gets f_{u,0}+\min\{f_{v,0},f_{v,1},f_{v,2},f_{v,3}\}$。
    • 对于 fu,1f_{u,1} 的转移,uu 不被选择,则需要 vv 不依赖 uu 染成蓝色。fu,1fu,1+min{fv,2,fv,3}f_{u,1}\gets f_{u,1}+\min\{f_{v,2},f_{v,3}\}
    • 对于 fu,2f_{u,2} 的转移,uu 被选择,则对 vv 不做要求。同时应当考虑 vvuu 染色的情况,此时 vv 应当满足被选择且不依赖父亲染色。$f_{u,2}\gets\min\{\min\{f_{v,0},f_{v,1},f_{v,2},f_{v,3}\}+f_{u,2},f_{u,0}+f_{v,2}\}$。
    • 对于 fu,3f_{u,3} 的转移,uu 不被选择,则需要 vv 不依赖 uu 染成蓝色。应当考虑 vvuu 染色的情况,vv 同样应当满足被选择且不依赖父亲染色。$f_{u,3}\gets\min\{\min\{f_{v,2},f_{v,3}\}+f_{u,3},f_{u,1}+f_{v,2}\}$。

    初始值 fu,0wu,fu,10f_{u,0}\gets w_u,f_{u,1}\gets 0。如果 uu 一开始为蓝色,则 fu,2wu,fu,30f_{u,2}\gets w_u,f_{u,3}\gets 0。否则 fu,2+,fu,3+f_{u,2}\gets +\infty,f_{u,3}\gets +\infty

    Code

    转移时应当注意顺序,不过更好的方式是使用临时数组来存储原来的 DP 值。

    constexpr int N=2e5+5,inf=1e9;using ll=long long;
    struct edge{int to,nxt;}e[N<<1];
    int head[N],cnt=0;char s[N];
    inline void add(int u,int v){e[++cnt]=(edge){v,head[u]};head[u]=cnt;}
    ll f[N][4],w[N],g[4];bool col[N];
    inline void dfs(int u,int fa)
    {
        f[u][0]=w[u];f[u][1]=0;f[u][2]=f[u][3]=inf;
        if(col[u]) f[u][2]=w[u],f[u][3]=0;
        for(int i=head[u];i;i=e[i].nxt)
        {
            int v=e[i].to;if(v==fa) continue;
            dfs(v,u);memcpy(g,f[u],sizeof(g));
            f[u][0]=min({f[v][0],f[v][1],f[v][2],f[v][3]})+g[0];
            f[u][1]=min(f[v][2],f[v][3])+g[1];
            f[u][2]=min(f[v][2]+g[0],g[2]+min({f[v][0],f[v][1],f[v][2],f[v][3]}));
            f[u][3]=min(f[v][2]+g[1],g[3]+min(f[v][2],f[v][3]));
        }
    }
    inline void work()
    {
        ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
        int n;cin>>n;for(int i=1,u,v;i<n;i++) cin>>u>>v,add(u,v),add(v,u);
        cin>>(s+1);for(int i=1;i<=n;i++) col[i]=(s[i]=='Y');
        for(int i=1;i<=n;i++) cin>>w[i];
        dfs(1,0);cout<<min(f[1][2],f[1][3])<<endl;
    }
    
    • 1

    信息

    ID
    7748
    时间
    1000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者