标签:
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