poj 2342 【Anniversary party】树形dp

题目传送门//res tp poj

题意

给出一棵有权树,求一个节点集的权值和,满足集合内的任意两点不存在边

分析

每个点有选中与不选中两种状态,对于第\(i\)个点,记选中为\(sel_i\),不选中为\(insel_i\)
若某一节点选中,则其子节点都不能选中。
若某一节点不选中,则其子节点有两种选择:1.选中 2.不选中

\[sel_i = val_i +\sum_j insel_j\]
\[insel_i = \sum_j max\{insel_j,sel_j\}\]
其中\(j\) 是\(i\)的子节点,\(val_i\)是节点\(i\)的权值
设\(rt\)为该树的根
则答案为
\[ans = max\{sel_{rt},insel_{rt}\}\]

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<deque>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i = (a);i>=(b);--i)
#define fo(i,a,b) for(int i =(a);i<(b);++i)
#define de(x) cout<<#x<<" = "<<x<<endl;
#define endl '\n'
#define ls(p) ((p)<<1)
#define rs(p) (((p)<<1)|1)
using namespace std;
typedef long long ll;
const int mn = 6e3 + 10;
int n;
int u[mn],inu[mn];
int val[mn];

struct E{
    int firs,lasts;
    int fa;
    int nextbro;
}e[mn];

void dfs(int r){
    int tpos = e[r].firs;
    while(tpos){
        dfs(tpos);
        tpos = e[tpos].nextbro;
    }
    tpos = e[r].firs;
    u[r] += val[r];
    while(tpos){
        u[r] += inu[tpos];
        inu[r] += max(inu[tpos],u[tpos]);
        tpos = e[tpos].nextbro;
    }
}

int main(){
    scanf("%d",&n);
    rep(i,1,n)scanf("%d",&val[i]);
    int tf,ts;
    rep(i,1,n){
        scanf("%d %d",&ts,&tf);
        if(e[tf].firs){
            e[e[tf].lasts].nextbro = ts;
            e[tf].lasts = ts;
        }
        else{
            e[tf].firs = e[tf].lasts = ts;
        }
        e[ts].fa = tf;
    }
    int root = 1;
    while(e[root].fa) root = e[root].fa;
    //de(root)
    dfs(root);
    printf("%d\n",max(u[root], inu[root]));
}

原文地址:https://www.cnblogs.com/tea-egg/p/11616342.html

时间: 2024-10-10 04:08:26

poj 2342 【Anniversary party】树形dp的相关文章

POJ 2342 Anniversary party (树形dp 入门题)

Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4810   Accepted: 2724 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure

POJ 2342 Anniversary party 树形dp入门

http://poj.org/problem?id=2342 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大. 对于每一个人,都有两种情况,选,或者不选.然后选了后,他的下属就只能不选了,如果它不选,下属可能选或者不选. 这样用dfs + 记忆化搜索,就好了 每次搜索,就是要求以第cur个节点为根的子树中,其中第cur个节点的状态是s

POJ 2342 Anniversary party 树形DP基础题

题目链接:http://poj.org/problem?id=2342 题目大意:在一个公司中,每个职员有一个快乐值ai,现在要开一个party,邀请了一个员工就不可能邀请其直属上司,同理邀请了一个人就不可以邀请其的直属员工, 问如何使得这个快乐值达到最大. 题解:对每个结点dp[i][0]表示不邀请这个员工,其子树达到的最大快乐值,dp[i][1]表示邀请i员工其子树达到的最大值. dp[i][0]=(i的全部员工的max(dp[u][1],dp[u][0)相加,也就是其子员工来或不来的最大快

POJ 2342 Anniversary Party ( 树形DP )

deque 的插入操作不一定有 vector 快 #include <iostream> #include <cstring> #include <fstream> #include <vector> using namespace std; #define NOT_SELECTED 0 #define SELECTED 1 #define SIZE 6001 vector< int > relations[SIZE]; bool visited

poj 2324 Anniversary party(树形DP)

/*poj 2324 Anniversary party(树形DP) ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值, ---于是当i去时,i的所有儿子都不能去:dp[i][1]=sum(dp[j][0])+a[i],其中j是i的儿子节点. ---当i不去时,i的儿子可去也可不去:dp[i][0]=sum(max(dp[j][0],dp[j][1])),j是i的儿子节点 ---边界条件:当i时叶子节点时,dp[i][

POJ 2342 Anniversary party (树dp)

题目链接:http://poj.org/problem?id=2342 有n个人,每个人有活跃值.下面n-1行u和v表示u的上司是v,有直接上司和下属的关系不能同时参加party,问你party最大的活跃值是多少. 也就是说一棵树中,选择的点不能是相邻的点,且要使活跃值最大. 简单的树形dp,任意选一个点开始遍历,从叶子节点开始回溯. dp[i][0]表示不选i节点最大的活跃度,则dp[i][1]表示选i节点最大的活跃度. i与j相连,dp[i][0] += max(dp[j][0], dp[j

poj 2342 &amp;&amp; hdu 1520 树形dp

题意:有n个人,接下来n行是n个人的价值,再接下来n行给出l,k说的是l的上司是k,这里注意l与k是不能同时出现的 链接:点我 dp[i][1] += dp[j][0], dp[i][0] += max{dp[j][0],dp[j][1]};其中j为i的孩子节点. 第二次做感觉已经很水了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #i

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行,每行输入

POJ 2342 &amp;&amp;HDU 1520 Anniversary party 树形DP 水题

一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点)都不能被邀请 2.每一个员工都有一个兴奋值,在满足1的条件下,要使得邀请来的员工的兴奋值最高 输出最高的兴奋值. 简单的树形DP dp[i][1]:表示以i为根的子树,邀请节点i的最大兴奋值 dp[i][0]:表示以i为根的子树,不邀请节点i的最大兴奋值 先根据入度找出整棵树的根节点, 然后一次DF

POJ Anniversary party 树形DP

/* 树形dp: 给一颗树,要求一组节点,节点之间没有父子关系,并且使得所有的节点的权值和最大 对于每一个节点,我们有两种状态 dp[i][0]表示不选择节点i,以节点i为根的子树所能形成的节点集所能获得的最大权值和 dp[i][1]表示选择节点i ,同上! 转移方程: dp[i][0]+=max(dp[i_son][1],dp[i_son][0])如果没选择的话,那么子树可选择可不选择 dp[i][1]+=dp[i_son][0] 选择了之后,子树只能不选择 最后输出max(dp[i][0],