1. 程式人生 > >URAL 1039 Anniversary Party

URAL 1039 Anniversary Party

表示 div 初始 clas ons cto tps urn c++

URAL 1039

思路:

樹形dp

狀態:dp[i][0]表示以i為根節點的子樹不選取i的最大貢獻

  dp[i][1]表示以i為根節點的子樹選取i的最大貢獻

初始狀態:dp[i][0]=0(if i is a leaf)

     dp[i][1]=a[i](if i is a leaf)

狀態轉移:

dp[i][0]=∑max(dp[g[i][j]][0],dp[g[i][j]][1])

dp[i][1]=a[i]+∑dp[g[i][j]][0]

代碼:

#include<bits/stdc++.h>
using namespace std;
#define
ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=6e3+5; vector<int>g[N]; int dp[N][2]; int a[N]; int in[N]; void dfs(int u){ if(g[u].size()==0){ dp[u][0]=0; dp[u][1]=a[u]; return ; } for(int i=0;i<g[u].size();i++){ dfs(g[u][i]); }
for(int i=0;i<g[u].size();i++){ dp[u][0]+=max(dp[g[u][i]][1],dp[g[u][i]][0]); dp[u][1]+=dp[g[u][i]][0]; } dp[u][1]+=a[u]; } int main(){ ios::sync_with_stdio(false); cin.tie(0); int n,u,v; cin>>n; for(int i=1;i<=n;i++)cin>>a[i];
while(cin>>u>>v){ if(u==0&&v==0)break; g[v].pb(u); in[u]++; } int root; for(int i=1;i<=n;i++){ if(in[i]==0){ root=i; break; } } dfs(root); cout<<max(dp[root][0],dp[root][1])<<endl; return 0; }

URAL 1039 Anniversary Party