其他分享
首页 > 其他分享> > 树形DP

树形DP

作者:互联网

树形 DP,即在树上进行的 DP。
由于树固有的递归性质,树形 DP 一般都是递归进行的。

树的最长路径

题目描述
给定一个含有 n 个节点的 树,以及树中每条边的权值 wedgei。
现需要在树中找出一条路径,使得该路径上所有边的权值之和最大。

思路:
记录以i为根节点的子树中,从子树某个节点到i的最长路和次长路。
那么以经过i的最长边就是最长路+次长路。
而且很明显可以递归求解。

闫氏DP分析法
状态表示—集合\(f_{1,i}\),\(f_{2,i}\): 以节点 i 为根的子树中,从子树某个节点到 i 的最长路为 f1,次长路为 f2
状态表示—属性: 路径长度的最大值 Max
状态计算.......
代码:

#include <bits/stdc++.h>
#define endl '\n'
#define int long long
#define pii pair<int, int>
#define pll pair<int, int>
#define ull unsigned long long
using namespace std;
const int N = 10010, M = N * 2;
int n;
int to[M], w[M], pre[M], h[N], idx;
void add(int a, int b, int c)
{
    to[idx] = b, w[idx] = c, pre[idx] = h[a], h[a] = idx++;
}
int ans = 0;
int dfs(int u, int fa)
{
    int d1 = 0, d2 = 0;
    for (int i = h[u]; i != -1; i = pre[i])
    {
        int j = to[i];
        if (j == fa)
            continue;
        int d = dfs(j, u)+w[i];
        if (d >= d1)
            d2 = d1, d1 = d;
        else if (d > d2)
            d2 = d;
    }
    ans = max(ans, d1 + d2);
    return d1;
}
void solve()
{
    memset(h, -1, sizeof h);
    cin >> n;
    for (int i = 0; i < n-1; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c), add(b, a, c);
    }

    dfs(1, -1);
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}

树的中心 换根DP

题意:
给定一棵树,树中包含 n 个结点(编号1~n)和 n−1 条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离 最近

思路:
思考一下:求一个节点的 最远距离 时,会有几种路径呢:

  1. 从当前节点往下,直到子树中某个节点的最长路径

  2. 从当前节点往上走到其父节点,再从其父节点出发且不回到该节点的最长路径

引入 换根DP 的思想
换根DP 一般分为三个步骤:

  1. 指定任意一个根节点
  2. 一次dfs遍历,统计出当前子树内的节点对当前节点的贡献
  3. 一次dfs遍历,统计出当前节点的父节点对当前节点的贡献,然后合并统计答案

我们先 dfs 一遍,预处理出当前子树对于根的最大贡献(距离)和 次大贡献(距离)

处理 次大贡献(距离) 的原因是:
如果 当前节点 是其 父节点子树 的 最大路径 上的点。此时 父节点子树 的 最大贡献 不能算作对该节点的贡献,就要使用次大贡献

因为我们的路径是 简单路径(不能 走回头路)

然后我们再 dfs 一遍,求解出每个节点的父节点对他的贡献(即每个节点往上能到的最远路径

两者比较,取一个 max 即可

代码:


主要参考:一只野生彩色铅笔
https://www.acwing.com/user/myspace/index/55909/

标签:int,路径,dfs,树形,节点,DP,d1
来源: https://www.cnblogs.com/kingwz/p/16548828.html