HDU - 1502 Anniversary party 【树形dp入门】

传送门
//一棵树, 有点权, 儿子和父亲不能同时选, 问可以得到的最大值是多少.
//这就是树形dp入门题. 所以方程还是比较好写的. dp[x][0] 代表不选这个点, dp[x][1]代表选这个点.
dp[i][1] += dp[j][0]; (j 是 i 的儿子)
dp[i][0] += max(dp[j][0], dp[j][1]); (同样的)

所以可以开始敲啦,注意处理下细节就行了, 具体处理请看代码

AC Code

const int maxn = 6e3+5;
int dp[maxn][2];
vector<int>g[maxn];
void dfs(int u,int fa)
{
    for(int i=0;iint to = g[u][i];
        if(to == fa) continue;
        dfs(to,u);
    }
    int len = g[u].size();  //因为加的双向边,所以叶结点不予考虑,然后特判根的情况.
    for(int i=0;i 1 || fa == -1);i++){
        int to = g[u][i];
        if(fa == to) continue;
        dp[u][1] += dp[to][0];
        dp[u][0] += max(dp[to][0],dp[to][1]);
    }
}
void solve()
{
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++) g[i].clear();
        Fill(dp,0);
        for(int i=1;i<=n;i++) scanf("%d",&dp[i][1]);
        int u,v;
        while(~scanf("%d%d",&u,&v) && u && v){
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1,-1);
        printf("%d\n",max(dp[1][1],dp[1][0]));
    }
}

这算是树形dp的开始吧, 在这借鉴了一下大佬说的一些经典树形dp的题目..

列出一些经典问题吧:

1:给出一棵树 每个节点有权值要求父节点和子节点不能同时取 求能够取得的最大值 (hdu1520)

2:给出一棵树, 求离每个节点最远的点的距离 (hdu2196)

3:1> 在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中允许攻克M个城堡并获得里面的宝物. 但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。求获得尽量多的宝物应该攻克哪M个城堡. (hdu1561)

题解:树形dp+背包
2> 每个节点有两个值bug和brain, 当清扫该节点的所有bug时就得到brain值,只有当父节点被清空时,才可以清扫它的子节点, 而清扫需要一定的人员. 给定M个人员, N个结点的树, 求最大brain和 (hdu1011)

3> 现在有n个村子,你想要用收买m个村子为你投票,其中收买第i个村子的代价是val[i]。但是有些村子存在从属关系,如果B从属于A国,则收买了A也意味着买通了B,而且这些关系是传递的。问你最小要付出的代价是多少?(poj3345)

4:1> 一棵树,定义每个节点的balance值:去掉这点节点后的森林里所有树的最大节点数。求出最小的balance值和其所对应的节点编号(poj1655)

2> 给你一棵无向树 T,要求依次去除树中的某个结点,求去掉该结点后变成的森林 T’ 中的最大分支。并要求该分支为去除的结点尽可能少。答案可能有多个,需要按照节点编号从小到大输出 (poj3107)

5:给一棵树, n结点<=1000, 和K< =200, 在这棵树上找大小为k的子树, 使其点权和值最大 (zoj3201)

6:给一个树状图,有n个点。求出,去掉哪个点,使得剩下的每个连通子图中点的数量不超过n/2。如果有很多这样的 点,就按升序输出。n<=10000 (poj2378)

7:一棵n个结点的带权无根树,从中删去一条边,使得剩下来的两棵子树的节点权值之和的绝对值最小,并求出得到的最 小绝对值 (poj3140)

8:给出一些点,有值,给出一些边,然后求去掉一条边后将分成连通的两部分,且两部分的差值最小 (hdu2242)

9:有n个点组成一个树,问至少要删除多少条边才能获得一棵有p个结点的子树 (poj1947)

10:一棵树n<=1000(节点的分支<=8),Snail在根处,它要找到在某个叶子处的house而其中一些节点上有worm,worm 会告诉它的house是否在这个子树上求Snail最快寻找到house走过路径的期望值 (poj2057)

11:给你一颗苹果树,有N个节点每个节点上都有一个苹果也就是有一个权值,当你经过这个节点是你将得到这个权值, 重复走节点是只能算一次,给你N-1条边。问你只能走K步能得到的最大权值和 (poj2486)

12:一颗二叉苹果树树上结苹果,要求剪掉几棵枝,然后求保留Q根树枝能保留的最多到苹果数 (ural1018)

13:给定一棵树,求最少连多少条边,使得每个点在且仅在某一个环内。 (poj1848)

14:在一棵树形的城市中建立一些消防站,但每个城市有一个最大距离限制,求需要的最小花费 (poj2152)

上面的题还是都做一做吧.

你可能感兴趣的:(树形dp)