一道很简单的树形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;
}
posted on 2011-07-22 08:24  奋斗青春  阅读(795)  评论(0编辑  收藏  举报