Algorithm 求n元树最大非邻接和的算法

Algorithm 求n元树最大非邻接和的算法,algorithm,tree,dynamic-programming,maximize,Algorithm,Tree,Dynamic Programming,Maximize,给定一个n元整数树,任务是找到子序列的最大和,约束条件是序列中没有两个数字共享树中的公共边。 例子: 1. / \ 2 5 / \ 3 4 最大非相邻和=3+4+5=12 以下是中概述的算法的错误扩展 但我不确定返回时交换exc_sum和inc_sum是否是实现结果的正确方法,我如何跟踪可能导致最大和的可能和,在这个示例中,左子树中的最大和是(1+3+4),而导致最终最大值的和是(3+4+5),那么应该如何跟踪(3+4)?如果所有存储在表中的中间量(< P>)可以说 dp[u]

给定一个n元整数树,任务是找到子序列的最大和,约束条件是序列中没有两个数字共享树中的公共边。 例子: 1. / \ 2 5 / \ 3 4 最大非相邻和=3+4+5=12 以下是中概述的算法的错误扩展


但我不确定返回时交换exc_sum和inc_sum是否是实现结果的正确方法,我如何跟踪可能导致最大和的可能和,在这个示例中,左子树中的最大和是(1+3+4),而导致最终最大值的和是(3+4+5),那么应该如何跟踪(3+4)?如果所有存储在表中的中间量(

< P>)可以说<强> dp[u] [SELECT] < /St>存储答案:最大子序列和没有两个节点有边,这样我们只考虑根结在节点<强> u>强>(这样选择<强> u < /强>)。现在您可以编写一个递归程序,其中每个递归的状态为(u,select),其中u表示正在考虑的子图的根,select表示是否选择节点u。因此,我们得到以下伪代码

     /* Initialize dp[][] to be -1 for all values (u,select) */
     /* Select is 0 or 1 for false/true respectively        */

     int func(int node , int select )
     {
         if(dp[node][select] != -1)return dp[node][select];
         int ans = 0,i;

         // assuming value of node is same as node number
         if(select)ans=node;

         //edges[i] stores children of node i
         for(i=0;i<edges[node].size();i++)
         {
             if(select)ans=ans+func(edges[node][i],1-select);
             else ans=ans+max(func(edges[node][i],0),func(edges[node][i],1));
         }
         dp[node][select] = ans;
         return ans;
     }

     // from main call, root is root of tree and answer is
     // your final answer
     answer = max(func(root,0),func(root,1));
/*初始化dp[][]为所有值的-1(u,选择)*/
/*选择值分别为0或1表示为假/真*/
int func(int节点,int选择)
{
如果(dp[node][select]!=-1)返回dp[node][select];
int ans=0,i;
//假设节点的值和节点号相同
如果(选择)ans=节点;
//边[i]存储节点i的子节点

对于(i=0;我想我不太明白这个例子——到标有和的术语的节点的路径应该是不相交的(没有共享的祖先,但可能是根)或者没有两个这样的节点是兄弟节点吗?@maverickz你对答案满意吗?还是还有疑问?@greybeard:根据问题描述,总和中包含的两个节点不能共享一条边,即不能有父子节点relationship@sasha当前位置解决方案很好!很抱歉,由于缺乏声誉,我无法投票。也不能他的算法被扩展到一个图,如果是这样的话,我们应该考虑每个节点的所有和的最大值作为一个起始节点吗?对于一个图,你是指一个一般的图形?测试用例不应该是4,1,1,2,1,5,2,3,2,4i是否已经指定了输入格式,并且给出了一个你可以在你的测试用例中运行的链接,我没有意识到前两个ARG。uments是边和根节点的数量,并且认为它们也是父子节点。
     /* Initialize dp[][] to be -1 for all values (u,select) */
     /* Select is 0 or 1 for false/true respectively        */

     int func(int node , int select )
     {
         if(dp[node][select] != -1)return dp[node][select];
         int ans = 0,i;

         // assuming value of node is same as node number
         if(select)ans=node;

         //edges[i] stores children of node i
         for(i=0;i<edges[node].size();i++)
         {
             if(select)ans=ans+func(edges[node][i],1-select);
             else ans=ans+max(func(edges[node][i],0),func(edges[node][i],1));
         }
         dp[node][select] = ans;
         return ans;
     }

     // from main call, root is root of tree and answer is
     // your final answer
     answer = max(func(root,0),func(root,1));