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