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 }

 

你可能感兴趣的:(part)