树形dp的基础题;
状态转移很简单:老爸没选,儿子可选可不选,最大就行;
老爸选了,儿子肯定不能选;
dp[root][0]+=max(dp[son][1],dp[son][0]);
dp[root][1]+=dp[son][0];
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #define maxn 6003 5 using namespace std; 6 7 int w[maxn],dp[maxn][2]; 8 vector<int>ve[maxn]; 9 bool vis[maxn]; 10 11 void dfs(int a) 12 { 13 vis[a]=1; 14 dp[a][1]=w[a]; 15 dp[a][0]=0; 16 int l=ve[a].size(); 17 for(int i=0; i<l; i++) 18 { 19 int v=ve[a][i]; 20 if(vis[v]) continue; 21 dfs(v); 22 dp[a][0]+=max(dp[v][1],dp[v][0]); 23 dp[a][1]+=dp[v][0]; 24 } 25 } 26 27 int main() 28 { 29 int n,a,b; 30 while(scanf("%d",&n)!=EOF) 31 { 32 memset(vis,0,sizeof vis); 33 memset(dp,0,sizeof dp); 34 for(int i=1; i<=n; i++) 35 { 36 scanf("%d",&w[i]); 37 ve[i].clear(); 38 } 39 while(scanf("%d%d",&a,&b)&&(a+b)) 40 { 41 ve[a].push_back(b); 42 ve[b].push_back(a); 43 } 44 dfs(1); 45 printf("%d ",max(dp[1][0],dp[1][1])); 46 } 47 return 0; 48 }