hdu1520 树形DP

 1 /*

 2  * 树形DP

 3  */

 4 #include<cstdio>

 5 #include<cstring>

 6 #include<vector>

 7 using namespace std;

 8 #define Max(x,y) (x>y?x:y)

 9 #define max 6000+10

10 

11 //dp[i][0],dp[i][1],当前节点为i,在父亲去或没去的情况下的最大值

12 vector<int> adj[max];

13 int d[max][2],a[max],n;

14 bool vis[max][2],in[max];

15 

16 int dp(int i,int j){

17     if(vis[i][j]){

18         return d[i][j];

19     }

20     vis[i][j]=true;

21     int& ans=d[i][j];

22 

23     if(!j){//i的父亲没去那么i可以去

24       ans=a[i];

25       for(int k=0;k<adj[i].size();k++){

26             ans+=dp(adj[i][k],1);

27       }

28     }

29 

30     int sum=0;//任何人都可以选择不去

31     for(int k=0;k<adj[i].size();k++){

32         sum+=dp(adj[i][k],0);

33     }

34     ans=Max(ans,sum);

35     return ans;

36 }

37 

38 int main(){

39     while(~scanf("%d",&n)){

40         memset(vis,false,sizeof(vis));

41         memset(in,false,sizeof(in));

42         memset(d,0,sizeof(d));

43         for(int i=1;i<=n;i++){

44             scanf("%d",&a[i]);

45             adj[i].clear();

46         }

47         int a,b;

48         while(scanf("%d%d",&a,&b)&&a&&b){

49             adj[b].push_back(a); in[a]=true;

50         }

51         int root;//找到校长,树根

52         for(int i=1;i<=n;i++){

53             if(!in[i]){

54                 root=i;break;

55             }

56         }

57         int ans=dp(root,0);

58         printf("%d\n",ans);

59     }

60 }

 

你可能感兴趣的:(HDU)