题目链接:poj 2342

题目大意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

思路:既然是树形dp,自然先建立一颗树了,这里用的是邻接表(L<-K)。找根的时候利用flag数组来标记所有儿子节点,那么没有标记的自然是根节点了。树形dp从叶子节点开始dp,所以深搜到叶子节点,然后不断回溯给父节点。在处理儿子节点时,父节点不参加的话儿子节点,取去与不去中的最大值;父亲节点参加那么儿子节点就不能去了。这里定义dp[][2],0表示不去,1表示去。具体运用参看代码。。。。。。。。。。。。。

/**************************************************************
    Problem:poj 2342
    User: youmi
    Language: C++
    Result: Accepted
    Time:16MS
    Memory:408K
****************************************************************/
//#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <sstream>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#define zeros(a) memset(a,0,sizeof(a))
#define ones(a) memset(a,-1,sizeof(a))
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define rep0(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define Max(a,b) (a)>(b)?(a):(b)
#define Min(a,b) (a)<(b)?(a):(b)
#define pt(a) printf("%d\n",a)
#define lson (step<<1)
#define rson (lson+1)
#define esp 1e-6
#define oo 0x3fffffff
#define TEST cout<<"*************************"<<endl

using namespace std;
typedef long long ll;
int n;
const int maxn=6000+10;
int dp[maxn][2];
int vis[maxn];
int head[maxn];
int flag[maxn];
int T;
struct side
{
    int v,next;
}e[maxn];
void init()
{
    T=0;
    zeros(vis);
    zeros(dp);
    zeros(flag);
    ones(head);
}
void build(int u,int v)
{
    e[T].v=v;
    e[T].next=head[u];
    head[u]=T++;
}
void tree_dp(int root)
{
    vis[root]=1;
    //pt(root);
    for(int i=head[root];~i;i=e[i].next)
    {
        int v=e[i].v;
        if(!vis[v])
        {
             tree_dp(v);
             dp[root][1]+=dp[v][0];
             dp[root][0]+=Max(dp[v][1],dp[v][0]);
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    /**<  int T_T;sc(T_T);
    for(int kase=1;kase<=T_T;kase++)*/
    //while(~sc(n))
    sc(n);
    {
        init();
        int root;
        rep1(i,n)
        {
            sc(dp[i][1]);
        }
        int u,v;
        rep1(i,n-1)
        {
            sc2(u,v);
            //printf("%d %d\n",u,v);
            build(v,u);
            flag[u]=1;
        }
        rep1(i,n)
        {
            if(!flag[i])
            {
                root=i;
                break;
            }
        }
        //pt(root);
        tree_dp(root);
        pt(Max(dp[root][1],dp[root][0]));
    }
    return 0;
}

 

posted on 2015-07-09 17:11  中子星  阅读(398)  评论(0编辑  收藏  举报