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; }