POJ2342-Anniversary party-树形DP入门

时间:2022-11-26 18:32:13

链接:poj.org/problem?id=2342

大意:一棵上下级关系树,直接上司不能和下属一起出席,每人都有权值,求出席party的人价值和最大值。

树形DP:dp[i]// 以i号人为根的关系树,dp [i][1]表示当前树 i 号人出席的价值和最大值,表示当前树 i 号人不出席的价值和最大值。

方程:dp[i][0] +=Σ max(dp[son][0],dp[son][1]);

   dp[i][1] +=Σ dp[son][0];

dp[son] 在dp[i]之前算,所以DFS。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
long long dp[6666][2];
int cnt;
int head[6666];
int v[6666];
int in[6666];
struct edge
{
    int to,next;
}E[6666];
void addedge(int from , int to)
{
    E[cnt].to = to;
    E[cnt].next = head[from];
    head[from] = cnt++;
}
void dfs(int now)
{
     for (int i = head[now] ; i != -1 ; i = E[i].next )
     {
        int to = E[i].to;
        dfs(to);
        dp[now][0] += max(dp[to][1],dp[to][0]);
        dp[now][1] += dp[to][0];
     }
     return;
}
int main()
{
    int N;
    //freopen("in.txt","r",stdin);
    ios::sync_with_stdio(false);
    cin >> N;
    memset(dp,0,sizeof(dp));
    for (int i = 1; i <= N ; i++)
    {
        cin >> dp[i][1];
    }
    int a,b;
    cnt = 0;
    memset(head,-1,sizeof head);
    long long start = N*(N+1)/2;
    while (cin >> a >> b &&a!=0&&b!=0)
    {
        addedge(b,a);
        start -= (long long)a;
    }
    dfs((int)start);
    cout << max(dp[start][1],dp[start][0]) << endl;
}