题目链接:poj 2342
题目大意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。
思路:既然是树形dp,自然先建立一颗树了,这里用的是邻接表(L<-K)。找根的时候利用flag数组来标记所有儿子节点,那么没有标记的自然是根节点了。树形dp从叶子节点开始dp,所以深搜到叶子节点,然后不断回溯给父节点。在处理儿子节点时,父节点不参加的话儿子节点,取去与不去中的最大值;父亲节点参加那么儿子节点就不能去了。这里定义dp[][2],0表示不去,1表示去。具体运用参看代码。。。。。。。。。。。。。
/************************************************************** Problem:poj 2342 User: youmi Language: C++ Result: Accepted Time:16MS Memory:408K ****************************************************************/ //#pragma comment(linker, "/STACK:1024000000,1024000000") //#include<bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <stack> #include <sstream> #include <cmath> #include <queue> #include <string> #include <vector> #define zeros(a) memset(a,0,sizeof(a)) #define ones(a) memset(a,-1,sizeof(a)) #define sc(a) scanf("%d",&a) #define sc2(a,b) scanf("%d%d",&a,&b) #define rep0(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define Max(a,b) (a)>(b)?(a):(b) #define Min(a,b) (a)<(b)?(a):(b) #define pt(a) printf("%d ",a) #define lson (step<<1) #define rson (lson+1) #define esp 1e-6 #define oo 0x3fffffff #define TEST cout<<"*************************"<<endl using namespace std; typedef long long ll; int n; const int maxn=6000+10; int dp[maxn][2]; int vis[maxn]; int head[maxn]; int flag[maxn]; int T; struct side { int v,next; }e[maxn]; void init() { T=0; zeros(vis); zeros(dp); zeros(flag); ones(head); } void build(int u,int v) { e[T].v=v; e[T].next=head[u]; head[u]=T++; } void tree_dp(int root) { vis[root]=1; //pt(root); for(int i=head[root];~i;i=e[i].next) { int v=e[i].v; if(!vis[v]) { tree_dp(v); dp[root][1]+=dp[v][0]; dp[root][0]+=Max(dp[v][1],dp[v][0]); } } } int main() { //freopen("in.txt","r",stdin); /**< int T_T;sc(T_T); for(int kase=1;kase<=T_T;kase++)*/ //while(~sc(n)) sc(n); { init(); int root; rep1(i,n) { sc(dp[i][1]); } int u,v; rep1(i,n-1) { sc2(u,v); //printf("%d %d ",u,v); build(v,u); flag[u]=1; } rep1(i,n) { if(!flag[i]) { root=i; break; } } //pt(root); tree_dp(root); pt(Max(dp[root][1],dp[root][0])); } return 0; }