Palace guards (tree dp)

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,head[2005],dp[2005][3],fa[2005],w[2005],cnt;

struct edge{
    int v,next;
}e[2005];

inline void add(int u,int v){
    e[++cnt].v=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}

inline int root(int v){
    if(fa[v]==-1)return v;
    return root(fa[v]);
}

//0:自无,父有 1:自有 2:自无父无,子有的有 
inline void guess(int u){
    int minn=2147483647,k=0;
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        guess(v);
        dp[u][1]+=min(dp[v][0],dp[v][1]);
        dp[u][0]+=min(dp[v][1],dp[v][2]);
        if(dp[v][1]<dp[v][2]){
            dp[u][2]+=dp[v][1];
            k++;
        }
        else{
            dp[u][2]+=dp[v][2];
            minn=min(minn,dp[v][1]-dp[v][2]);
        }
    }
    dp[u][1]+=w[u];
    if(k==0)dp[u][2]+=minn;
}

int main(){
    memset(head,-1,sizeof(head));
    memset(fa,-1,sizeof(fa));
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        int u,k,m;
        scanf("%d%d%d",&u,&k,&m);
        w[u]=k;
        while(m--){
            int x;
            scanf("%d",&x);
            add(u,x);
            fa[x]=u;
        }
    }
    int rt=root(1);
    guess(rt);
    printf("%d\n",min(dp[rt][1],dp[rt][2]));
}

Guess you like

Origin www.cnblogs.com/Y15BeTa/p/11269059.html