HDOJ树形DP专题之Anniversary party

题目链接

没有上司的晚会,经典的树形DP题。

View Code
 1 #include <stdio.h>
 2 #include <memory.h>
 3 #define MAX(a,b) ((a)>(b)?(a):(b))
 4 #define N 6000
 5 int a[N],p[N],d[N],c[N],vis[N],sums[N],sumgs[N],dmax,n;
 6 int fd(int k)
 7 {
 8   if(!vis[k]) return d[k]=0;
 9   if(d[k])  return d[k];
10   return d[k]=fd(p[k])+1;
11 }
12 int main()
13 {
14   int i,j,u,v,ans;
15   while(~scanf("%d",&n))
16   {
17     for(i=0;i<n;i++)  scanf("%d",&a[i]);
18     memset(vis,0,sizeof(vis));
19     memset(d,0,sizeof(d));
20     while(scanf("%d%d",&u,&v))
21     {
22       if(u==0 && v==0)  break;
23       u--,v--;
24       p[u]=v;
25       vis[u]=1;
26     }
27     dmax=0;
28     for(i=0;i<n;i++)  dmax=MAX(dmax,fd(i));
29     memset(sums,0,sizeof(sums));
30     memset(sumgs,0,sizeof(sumgs));
31     for(i=dmax;i>=0;i--)
32     {
33       for(j=0;j<n;j++)if(d[j]==i)
34       {
35         c[j]=MAX(sums[j],MAX(sumgs[j],sumgs[j]+a[j]));
36         if(i>0) sums[p[j]]+=c[j];
37         if(i>1) sumgs[p[p[j]]]+=c[j];
38       }
39     }
40     ans=0;
41     for(i=0;i<n;i++)if(!vis[i])  ans+=c[i];
42     printf("%d\n",ans);
43   }
44   return 0;
45 }
原文地址:https://www.cnblogs.com/algorithms/p/2471646.html