首页 > 代码库 > poj 2342 Anniversary party,树形DP easy

poj 2342 Anniversary party,树形DP easy

poj 2342 Anniversary party

没有上司的晚会
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起与会。
程序名:party
输入格式:
第一行一个整数N。(1<=N<=6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出格式:
输出最大的快乐指数。
输入样例:
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输入样例:
5
来源:URAL



树形结构上的动态规划

设:

dp[i][0] 表示以i为根,i自己不参加party的最大快乐指数。

dp[i][1] 表示以i为根,i自己参加pary的最大快乐指数。


dp[i][0] = sigma( max(dp[j][0], dp[j][1]) );     j为i的子节点

dp[i][1] = sigma( dp[j][0] );



#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 10000;

vector<int> G[maxn];
int fa[maxn], vis[maxn], val[maxn];
int dp[maxn][2];
int root;
void dfs(int u)
{
    vis[u] = 1;
    dp[u][0] = 0; dp[u][1] = val[u];
    for(int i=0; i<G[u].size(); ++i)
    {
        int v = G[u][i];
        if(!vis[v]) dfs(v);
        dp[u][0] += max(dp[v][0], dp[v][1]);
        dp[u][1] += dp[v][0];
    }
}
int main()
{
    int n, i, u, v;
    scanf("%d", &n);
    for(i=1; i<=n; ++i) scanf("%d", &val[i]);
    while(~scanf("%d%d", &u, &v))
    {
        if(u==0 && v==0) break;
        fa[u] = v;
        G[v].push_back(u);
    }

    for(i=1; fa[i]; ++i);
    dfs(root=i);
    printf("%d\n", max(dp[root][0], dp[root][1]));
    return 0;
}