标签:
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 4825 | Accepted: 2732 |
Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
思路:找到根节点,开始往下搜索,从叶子节点往上递归,记录子节点信息。
对于当前节点有两个选择,选或者不选;
dp[u][0]+=max(dp[v][1],dp[v][0]); //当前节点不选,则子节点可选可不选
dp[u][1]+=dp[v][0]; // 选择当前节点,则子节点必不能选
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define N 6005
int dp[N][2];
int pre[N],vis[N];
vector<int>g[N];
void dfs(int u)
{
int i,v;
vis[u]=1;
for(i=0;i<(int)g[u].size();i++)
{
v=g[u][i];
if(!vis[v])
dfs(v);
dp[u][0]+=max(dp[v][1],dp[v][0]);
dp[u][1]+=dp[v][0];
//printf("%d: %d %d %d\n",u,dp[u][0],dp[v][1],dp[v][0]);
//printf("%d %d\n",dp[u][1],dp[v][0]);
}
}
int main()
{
int i,n,u,v,root;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&dp[i][1]);
dp[i][0]=0;
pre[i]=i;
g[i].clear();
}
while(scanf("%d%d",&u,&v),u||v)
{
pre[u]=v;
root=v;
g[v].push_back(u);
}
root=1; //小心只有一个人的情况
while(pre[root]!=root) //找到根节点
root=pre[root];
memset(vis,0,sizeof(vis)); //记录访问过的节点
dfs(root);
printf("%d\n",max(dp[root][1],dp[root][0]));
return 0;
}
标签:
原文地址:http://blog.csdn.net/u011721440/article/details/45057547