题意: n个人参加party,已知每人的欢乐值,给出n个人的工作关系树,一个人和他的顶头上司不能同时参加,party达到的最大欢乐值。
分析:dp[i][f],以i为根的子树,f=0,i不参加,f=1,i参加 能达到的最大欢乐值。i参加i的孩子不能参加,i不参加,其孩子参不惨加都行(取最大值)。
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; struct tree{ int u,v,next; } t[6010]; int par[6010],dp[6010][2],n,head[6010],len,root; void add(int a,int b){ t[len].u=a; t[len].v=b; t[len].next=head[a]; head[a]=len++; } void dfs(int root){ for(int i=head[root];i!=-1;i=t[i].next){ int son=t[i].v; dfs(son); dp[root][0]+=max(dp[son][0],dp[son][1]); dp[root][1]+=dp[son][0]; } } int main() { while(~scanf("%d",&n)){ memset(par,0,sizeof(par)); memset(dp,0,sizeof(dp)); memset(head,-1,sizeof(head)); for(int i=1;i<=n;++i) scanf("%d",&dp[i][1]); int c,f; len=0; while(scanf("%d%d",&c,&f)){ if(c==0&&f==0)break; add(f,c); par[c]=1; } for(int i=1;i<=n;++i){ if(!par[i]){ root=i; break; } } dfs(root); printf("%d\n",max(dp[root][0],dp[root][1])); } return 0; }
时间: 2024-12-29 06:54:03