树形dp学习

学习博客:https://www.cnblogs.com/qq936584671/p/10274268.html

树的性质:n个点,n-1条边,任意两个点之间只存在一条路径,可以人为设置根节点,对于任意一个节点只存在至多一个父节点,其余为子节点。

记忆化树形dp模型较为抽象难以理解,以下通过由浅到深的方式解析树形dp以及树的性质。

树形dp求树的直径:(在一颗树里找到点X,Y,使得|XY|最大)

如图,我们令A为根节点,令dfs遍历顺序为ABDGHEFC。

在我们的dfs计算过程中,我们从下往上求解每一个节点,总的来说我们要求两个东西:

1、以每一个节点为根,所能到达的最长路径dp【u】

2、以每一个节点为根,它下面的的树的最长路径ans(其实就是找到 两个没有重复路径的子树,例如以B为根节点,会找到BDG+BE而不会找到BDG+BDH)

然后将子树中以子树根为起点所能到达的最长路径传给父节点,最后得出答案

具体看下面代码:

struct Node
{
    int nex,val;
};
vector<Node>node[maxn];//node[u][i].nex代表该节点的子节点  node[u][i].val代表该节点与子节点之间路径的权值
void dfs(int u,int fa)//该节点和该节点的父亲
{
    for(int i=0;i<node[u].size();i++)
    {
        int v=node[u][i].nex;
        if(v!=fa)//防止回到父节点
        {
            dfs(v,u);//
            ans=max(ans,d[u]+d[v]+node[u][i].val);//这个必须在下面一步的前面
            d[u]=max(d[u],d[v]+node[u][i].val);
        }
    }
}

理解了基本的树形dp之后,开始下面的练习:

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/10295035.html