1. 程式人生 > >樹形dp學習

樹形dp學習

防止 基本 技術分享 父節點 必須 最長路 div cnblogs 們的

學習博客: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之後,開始下面的練習:

樹形dp學習