HDU1520.Anniversary party(樹形DP&DFS)
思路:狀態轉移方程有兩個:1.不選父結點,則加上子結點選或者不選的最大值,2.選父結點,則加上不選子結點的最大值。具體看代碼。
AC代碼:
#include<bits/stdc++.h>
using namespace std;
const int N=6e3+5;
int dp[N][2],n,w[N],fa[N],a,b;
vector<int>e[N];
void dfs(int u){
dp[u][0]=0,dp[u][1]=w[u];
for(auto v:e[u]){
dfs(v);
dp[u][0]+=max(dp[v][0],dp[v][1]);//不選父結點
dp[u][1]+=dp[v][0];//選父結點.
}
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++) scanf("%d",&w[i]),e[i].clear(),fa[i]=0;//初始化
while(scanf("%d%d",&a,&b)){
if(!a&&!b) break;
e[b].push_back(a);//有向邊
fa[a]=b;
}
int rt=1;
while(fa[rt]) rt=fa[rt];//找根.
dfs(rt);
printf("%d\n",max(dp[rt][0],dp[rt][1]));
}
return 0;
}