Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6070 | Accepted: 3497 |
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
Source
任何一个点的取舍可以看作一种决策,那么状态就是在某个点取的时候或者不取的时候,以他为根的子树能有的最大活跃总值。分别可以用f[i,1]和f[i,0]表示第i个人来和不来。
当i来的时候,dp[i][1] += dp[j][0];//j为i的下属
当i不来的时候,dp[i][0] +=max(dp[j][1],dp[j][0]);//j为i的下属
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdlib> #include<stack> #include <queue> #include <set> #include <map> using namespace std; const int inf = 2147483647; const double PI = acos(-1.0); const double e = 2.718281828459; const int mod = 1000000009; typedef long long LL; //freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取 //freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中cin int dp[7000][2]; int v[7000], f[7000], vis[7000], n, m; void dp_dfs(int root) { vis[root] = 1; for (int i = 1; i <= n; ++i) { if (f[i] == root && !vis[i]) { dp_dfs(i); dp[root][1] += dp[i][0]; dp[root][0] += max(dp[i][0], dp[i][1]); } } } int main() { int i, j; while (~scanf("%d", &n)) { memset(dp, 0, sizeof(dp)); for (i = 1; i <= n; ++i) { scanf("%d", &dp[i][1]); } int L, K; memset(f, 0, sizeof(f)); memset(vis, 0, sizeof(vis)); int root; while (~scanf("%d%d", &L, &K)) { if (L == 0 && K == 0) break; f[L] = K; root = L; } while (f[root] != 0) { root = f[root];//因为只存在一颗树, 所以只需找到根节点然后往下递归即可 } dp_dfs(root); printf("%d\n", max(dp[root][0], dp[root][1])); } }