hdu 1520 单纯树形dp

4 篇文章 0 订阅

开始被这道题坑了,觉得一个上司的下属不止一个,然后就把它转成了二叉树做,然后把自己都绕进去了。

其实,这道题用原图dp就可以了。

dp方程: f[v][1]+=f[v.son][0];

                 f[v][0]+=max{f[v.son][0],f[v.son][1]};

我的代码是直接建立的有向边,直接遍历所有的边。

附上代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;


struct node{int to,next;};
node e[100861];

int head[6118];
int n,a[6118];
int f[6118][2];
  
int size;                        
void tjb(int x,int y)
{
  size++;
  e[size].next=head[x];
  head[x]=size;
  e[size].to=y;
}

int dp(int v,int p )
{
  if(f[v][p]==-1)
  {
  	f[v][p]=0;
  	if(p)
  	{
  		for(int i=head[v];i;i=e[i].next)
  		   f[v][p]+=dp(e[i].to,0);
  	    f[v][p]+=a[v];
	  }
  	else
  	  for(int i=head[v];i;i=e[i].next)
  	    f[v][p]+=max(dp(e[i].to,1),dp(e[i].to,0));
  }
	return f[v][p];
}

int ru[6118];

int main()
{
while(cin>>n)
{
    memset(e,0,sizeof(e));
    memset(head,0,sizeof(head));
    memset(a,0,sizeof(a));

    for(int i=1;i<=n;i++)
      scanf("%d",&a[i]);
    int x,y;
    
    memset(ru,0,sizeof(ru));
    size=0;
    scanf("%d%d",&x,&y);
    while(x!=0&&y!=0)
    {
      tjb(y,x);
      ru[x]++;
      scanf("%d%d",&x,&y);
    }
    int rep=0;
    for(int i=1;i<=n;i++)
      if(ru[i]==0) rep=i;
    int ans=0;
    
    memset(f,-1,sizeof(f));
    ans=dp(rep,0);
    ans=max(ans,dp(rep,1));
    
    cout<<ans<<endl;
}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值