一道很简单的树形DP,果断不解释,直接贴代码:
# include<stdio.h>
# include<string.h>
# define N 6005
struct node{
int from,to,next;
}edge[2*N];
int head[N],tol,visit[N],val[N],degree[N],dp[N][3];
void add(int a,int b)
{
edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
}
int max(int a,int b)
{
return a>b?a:b;
}
void dfs(int root)
{
int j,u,ans1,ans0;
visit[root]=0;
ans1=ans0=0;
for(j=head[root];j!=-1;j=edge[j].next)
{
u=edge[j].to;
if(!visit[u]) dfs(u);
ans0+=max(dp[u][0],dp[u][1]);
ans1+=dp[u][0];
}
dp[root][1]=ans1+val[root];//表示该节点选上时 以该节点为根的子树所能选取的最大值
dp[root][0]=ans0;//表示该节点未选上时,以该节点为根的子树所能选取的最大值
}
int main()
{
int i,n,sum,a,b;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&val[i]);
memset(head,-1,sizeof(head));
memset(degree,0,sizeof(degree));
tol=0;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a==0 && b==0) break;
add(b,a);
degree[a]++;
}
memset(visit,0,sizeof(visit));
memset(dp,0,sizeof(dp));
sum=0;
for(i=1;i<=n;i++)
{
if(degree[i]==0)
{
dfs(i);
sum+=max(dp[i][0],dp[i][1]);
}
}
printf("%d\n",sum);
}
return 0;
}
浙公网安备 33010602011771号