poj2342 Anniversary party

来源:互联网 发布:炉石传说盒子mac怎么用 编辑:程序博客网 时间:2024/05/17 07:33
/* * poj2342 AC * 典型的树状DP。 * dp[i][0]表示员工i参加舞会的最大值,dp[i][1]表示员工i不参加舞会的最大值。 * * dp[i][0] = max(dfs(son[i],1)); * i参加则i的儿子结点一定不能参加。 * dp[i][1] = max(dfs(son[i],0),dfs(son[i],1)); * i不参加则i的儿子结点可参加,也可以不参加。 * * 最初居然考虑错误,实在不应该,此题和摘苹果那题还是有区别的,每个结点要记录两个 * 状态,而非一个。 * */#include<cstdio>#include<algorithm>#include<memory.h>#define MIN (-(1<<30))using namespace std;int tree[6005],conv[6005],head[6005],next[6005],num[6005],root;long dp[6005][2];long dfs(int x,int state){    if(dp[x][state]!=MIN) return dp[x][state];    long i;    if(num[x]==0)    {        dp[x][0] = conv[x],dp[x][1] = 0;        return dp[x][state];    }    if(state)    {        for(dp[x][state]=0,i=head[x];i;i=next[i])            dp[x][state] += max(dfs(tree[i],0),dfs(tree[i],1));    }else    {        for(dp[x][state]=conv[x],i=head[x];i;i=next[i])            dp[x][state] += dfs(tree[i],1);    }    return dp[x][state];}int main(){    int n,i,j,k,tot;//    FILE* fin;//    fin = fopen("d.in","r");//    fscanf(fin,"%d",&n);    scanf("%d",&n);    for(i=1;i<=n;i++)    {        dp[i][0] = dp[i][1] = MIN;        scanf("%d",&conv[i]);//        fscanf(fin,"%d",&conv[i]);    }    memset(num,0,sizeof(num));    for(root=(1+n)*n/2,tot=0,i=1;i<=n-1;i++)    {        scanf("%d%d",&j,&k);//        fscanf(fin,"%d%d",&j,&k);        tree[++tot] = j,next[tot] = head[k],head[k] = tot,num[k]++,root -= j;    }    long ans;    ans = max(dfs(root,0),dfs(root,1));    printf("%ld\n",ans);    return 0;}

原创粉丝点击