树的最大独立集(1初步)

来源:互联网 发布:桂树焉知泰山之高的焉 编辑:程序博客网 时间:2024/04/30 10:53

poj2342


   先预热一下,开始先从这个入手,然后再做poj3342,实质都是一样的。


   题意:输入的前n个单数是每个人的快乐程度,就当做价值吧,后n-1个是关系,最后以0 0 结束关系。求整体价值最大,要求他们每个人的关系不能是直接的上下属,即结点间不相邻。

   注意: 价值 在这题中 有正有负 , 人数是<6000 ,整形sum 计算价值是足够的。


   思想: 是结点对结点的递推,而不会一层对上一层的递推。

        有两个状态,1 .结点u 和 它的子节点的子节点集

                   2 .结点u的子节点集

         (那么就应该用两个空间变量去存储更新)

         由于价值有正有负,要求它的最大值,那么,max()进行更新


         每种状态求得的是  该结点的最大价值,由该节点去推 父节点和父父节点 




#include<stdio.h>#include<string.h>#define max(a,b) a>b?a:bint dp[6001][2],par[6001];void dfs( int r ,int n){int i,m;    for(i = 1;i <= n ;i++ ){if(par[i] == r){dfs(i , n);m =  max(dp[i][0] , dp[i][1]);dp[r][0] = max(dp[r][0] , m + dp[r][0]);if(par[r]!=0)dp[par[r]][1] = max(dp[par[r]][1] , m + dp[par[r]][1]);}}}int main(){int n,i,j;int c,f,m,root;while(scanf("%d",&n)!=EOF){memset(par,0,sizeof(par));    memset(dp,0,sizeof(dp));for(i= 1 ;i <= n;i++) scanf("%d",&dp[i][1]);root = 0;for(i= 0;i<n;i++){scanf("%d %d", &c ,&f);if(c== 0 && f == 0)break;            par[c] =f;if(par[f] == 0)root = f;}dfs(root , n);m =  max(dp[root][0] ,dp[root][1]);printf("%d\n",m);}return 0;}

0 0
原创粉丝点击