【poj2342】 Anniversary party

http://poj.org/problem?id=2342 (题目链接)

题意

  没有上司的舞会。。。

Solution

  树形dp入门题。

  dp[i][1]表示第i个节点的子树当节点i去时的最大值,dp[i][0]表示第i个节点的子树当节点i不去时的最大值。转移很好转,dp[i][0]=max(dp[j][1],dp[j][0]) (j是i的儿子),dp[i][1]=dp[j][0] (j是i的儿子)。

代码

// poj2342
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483647
#define Pi 3.1415926535898
#define fre(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;
LL getint() {
    LL x=getchar(),t=0,f=1;if (x>'9' || x<'0') {if (x=='-') f=-1;x=getchar();}
    while (x>='0' && x<='9') {t=t*10+x-48;x=getchar();}return t*f;
}
void putint(LL x) {
    if (x<0) putchar('-'),x=-x;
    if (x>9) putint(x/10);putchar(x%10+48);
}

int dp[1000010][5],n,f[1000010],x,y;
bool b[1000010];

void tree_dp(int u) {
    b[u]=1;
    for (int i=1;i<=n;i++) 
        if (!b[i] && f[i]==u) {
            tree_dp(i);
            dp[u][1]+=dp[i][0];
            dp[u][0]+=max(dp[i][1],dp[i][0]);
        }
}
int main() {
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&dp[i][1]);
    for (int i=1;i<=n-1;i++) 
        scanf("%d%d",&x,&y),f[x]=y;
    int u=n;
    while (f[u]) u=f[u];
    tree_dp(u);
    printf("%d",max(dp[u][1],dp[u][0]));
    return 0;
}

  

posted @ 2016-09-27 21:18  MashiroSky  阅读(220)  评论(0编辑  收藏  举报