JLOI/SHOI2016侦查守卫

Posted aurora2004

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JLOI/SHOI2016侦查守卫相关的知识,希望对你有一定的参考价值。

技术图片
技术图片

SOL:

(f[i][j]i)点向上(j)层都可以被监视最小代价(当前点为第0层)

(g[i][j]i)点向下(j)层都无法别监视最小代价(当前点为第1层)

初始值:

需守卫的点:(f[x][0]=g[x][0]=w[x])

其余点:(f[x][0]=g[x][0]=0)

所有点:(f[x][i]=w[x](i>0))

转移方程:

[f[x][i]=min(f[x][i]+min(g[v][i],f[v][i+1]),g[x][i+1]+f[v][i+1])]

[f[x][i]=min(f[x][i],f[x][i+1])]

[g[x][0]=f[x][0]]

[g[x][i]+=g[v][i-1]]

[g[x][i]=min(g[x][i],g[x][i-1])]

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f==1?x:-x;
}
const int N=5e5+4,D=24;
int n,m,d,a[N],f[N][D],g[N][D],w[N];
vector<int>e[N];
void dfs(int x,int fa){
    if(a[x])f[x][0]=g[x][0]=w[x];
    else f[x][0]=g[x][0]=0;
    for(int i=1;i<=d;i++)f[x][i]=w[x];
    for(auto v:e[x]){
        if(v==fa)continue;
        dfs(v,x);
        for(int i=d;i>=0;i--){
            f[x][i]=min(min(f[x][i]+g[v][i],g[x][i+1]+f[v][i+1]),f[x][i]+f[v][i+1]);
            f[x][i]=min(f[x][i+1],f[x][i]);
        }
        g[x][0]=f[x][0];
        for(int i=1;i<=d+1;i++){
            g[x][i]=g[x][i]+g[v][i-1];
            g[x][i]=min(g[x][i],g[x][i-1]);
        }
    }
}
int main(){
    n=read();d=read();
    for(int i=1;i<=n;i++)w[i]=read();
    m=read();
    for(int i=1;i<=m;i++)a[read()]=1;
    for(int i=1,u,v;i<n;i++){
        u=read();v=read();
        e[u].push_back(v);e[v].push_back(u);
    }
    memset(f,0x3f,sizeof(f));
    dfs(1,0);
    cout<<f[1][0];
    return (0-0);
}

以上是关于JLOI/SHOI2016侦查守卫的主要内容,如果未能解决你的问题,请参考以下文章

[JLOI2016/SHOI2016]侦察守卫(树形dp)

bzoj4557

p3267 [JLOI2016/SHOI2016]侦察守卫

4557: [JLoi2016]侦察守卫|树形DP

4557: [JLoi2016]侦察守卫|树形DP

如何在其正文中解开守卫声明?