题目链接:https://vjudge.net/problem/POJ-2342
简单题意:一棵有点权的树,选出一些不相邻的结点使得总权值最大
f[i][0/1]表示以i为根,不选/选i能得到的最大值,则有f[i][0]=Σmin(f[j][0],f[j][1])+h[i],f[i][1]=Σf[j][0],j是i的子结点。最后答案为max(f[root][0],f[root][1])。注意这题要先把根求出来,也就是入度为0的点。
#include<bits/stdc++.h> #define ll long long #define pb push_back using namespace std; const int maxn=1e4+10; vector<int> son[maxn]; int n,i,j,k,l,root,h[maxn],fa[maxn],f[maxn][2]; void dp(int u){ if (son[u].size()==0){ f[u][0]=0; f[u][1]=h[u]; return; } for (int i=0;i<son[u].size();i++){ int v=son[u][i]; dp(v); f[u][0]+=max(f[v][0],f[v][1]); f[u][1]+=f[v][0]; } f[u][1]+=h[u]; } int main(){ std::ios::sync_with_stdio(false); cin>>n; for (i=1;i<=n;i++) cin>>h[i]; for (i=1;i<=n-1;i++){ cin>>l>>k; son[k].pb(l); fa[l]=1; } for (i=1;i<=n;i++) if (fa[i]==0) root=i; cin>>l>>k; dp(root); cout<<max(f[root][0],f[root][1])<<endl; return 0; }