hdu 1520

一道很简单的树形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;

}

你可能感兴趣的:(HDU)