hdu1520树形dp第一题
判断最大的欢喜值,如果上司来了,直系下属就不来
如果子节点j不来那么dp[i][1]+=dp[j][0];
如果子节点j来那么dp[i][0]+=max(dp[j][0],dp[j][1]);//因为j不来i也可以不来
递归的求子节点值
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdio> #include<cassert> #include<iomanip> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pi acos(-1) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-9; const int N=6000+10,maxn=5000+10,inf=0x3f3f3f3f; vector<int>v[N]; int dp[N][2],father[N]; void tree_dp(int x) { for(int i=0;i<v[x].size();i++) { int y=v[x][i]; tree_dp(y); dp[x][1]+=dp[y][0]; dp[x][0]+=max(dp[y][0],dp[y][1]); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; while(cin>>n){ for(int i=1;i<=n;i++) { cin>>dp[i][1]; v[i].clear(); father[i]=i; dp[i][0]=0; } int a,b; while(cin>>a>>b,a&&b){ v[b].push_back(a); father[a]=b; } int root=1; while(root!=father[root])root=father[root]; tree_dp(root); cout<<max(dp[root][1],dp[root][0])<<endl; } return 0; }